在返回PartialViewResult时,更新主窗体以显示自定义验证消息

本文关键字:显示 自定义 验证 消息 窗体 PartialViewResult 返回 更新 | 更新日期: 2023-09-27 18:30:12

我有一个主视图,这个主视图有一个div标记,在Ajax调用控制器后,它将包含一个局部视图。

以下是负责启动ajax调用的部分视图:

@model EDR.Presentation.WebMain.ViewModels.MvcPatientDetailsHIVViewModel
<div class="form-group-sm">
    @Html.LabelFor(m => m.HIVTestTestDate, new { @class = "control-label" })
    @Html.EditorFor(m => m.HIVTestTestDate, new { htmlAttributes = new { @class = "form-control form-control-custom-50" } })
</div>
<div class="form-group-sm">
    @Html.LabelFor(m => m.HIVTestTestResult, new { @class = "control-label" })
    @Html.DropDownListFor(m => m.HIVTestTestResult, Model.SelectList_HIVTestedResult, new { @class = "form-control form-control-custom-50" })
</div>
<div class="form-group-sm">
    @Html.LabelFor(m => m.HIVTestCD4Count, new { @class = "control-label" })
    @Html.EditorFor(m => m.HIVTestCD4Count, new { htmlAttributes = new { @class = "form-control form-control-custom-50" } })
</div>
<input type="button" value="Add" id="btnAddNewTest" class="btn btn-info" />
<input type="button" value="Cancel" id="btnCancelAdd" class="btn btn-danger" />

这是我的ajax调用:

$('#btnAddNewTest').on("click", function () {
        var date = $('#HIVTestTestDate').val();
        var result = $('#HIVTestTestResult').val();
        var cd4 = $('#HIVTestCD4Count').val();
        var pID = $('#PatientID').val();
        var dataToSend = { patientID: pID, testDate: date, resultID: result, cd4Count: cd4 };
        $.ajax({
            url: '/HIVInformation/AddHIVTest/',
            type: 'post',
            data: dataToSend,
            success: function (partialViewReceived) {
                $('#HIVTestCollection').html(partialViewReceived);
            }
        });
    });

以下是ajax调用所调用的控制器中的操作:

public PartialViewResult AddHIVTest(Guid patientID, DateTime testDate, Guid resultID, int cd4Count)
        {
            MvcPatientDetailsHIVViewModel model = new MvcPatientDetailsHIVViewModel(patientID);
            model.LoadAllData();
            try
            {
                //add the HIV Test
                model.HIVTestResult = new Common.Models.PatientHIVTestModel()
                {
                    ID = Guid.NewGuid(),
                    PatientID = patientID,
                    TestDate = testDate,
                    HIVTestResultID = resultID,
                    CD4Count = cd4Count
                };
                //call the add method
                model.AddHIVTestResults();
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
            }
            return PartialView("_HIVTestCollection", model);
        }

这是在尝试添加新的HIV测试成功/失败后加载的部分视图。

@model EDR.Presentation.WebMain.ViewModels.MvcPatientDetailsHIVViewModel
@using EDR.Presentation.WebMain.Helpers
@if (Model.PatientHIVTestCollection != null && Model.PatientHIVTestCollection.Count > 0)
{
    <div class="table-responsive">
        <table class="table table-hover">
            <thead>
                <tr>
                    <th>Date</th>
                    <th>Test Result</th>
                    <th>CD4 Count</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var hivTest in Model.PatientHIVTestCollection.OrderByDescending((x) => x.TestDate))
                {
                    <tr>
                        <td>@RazorHelper.ToDateString(() => hivTest.TestDate)</td>
                        <td>@RazorHelper.ToString(() => hivTest.HIVTestResult.DisplayName)</td>
                        <td>@RazorHelper.ToString(() => hivTest.CD4Count)</td>
                        <td>
                            @Ajax.ActionLink("Edit", "EditHIVTest", new { patientID = Model.PatientID, testID = hivTest.ID }, new AjaxOptions() { HttpMethod = "get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "testEdit" }, new { @class = "btn btn-info" })
                            @Ajax.ActionLink("Delete", "DeleteHIVTest", new { patientID = Model.PatientID, testID = hivTest.ID }, new AjaxOptions() { HttpMethod = "get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "HIVTestCollection" }, new { @class = "btn btn-danger" })
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
}
else
{
    <text>No Data to display</text>
}

在捕捉到异常后,我已经验证了验证消息已添加到ModelState中。

我知道这个部分视图是动态添加到主视图的,但我如何重置主视图以显示添加到ModelState的验证消息。我不想在局部视图中显示验证消息。

这是主视图上的部分视图,用于显示验证消息。

@model ModelStateDictionary
@if (!Model.IsValid)
{
    <div class="panel panel-danger">
        <div class="panel-heading">Validation Errors</div>
        <div class="panel-body">
            <ul>
                @foreach (var modelError in
                             Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
                {
                    <li>@modelError.ErrorMessage</li>
                }
            </ul>
        </div>
    </div>
}

如有任何帮助,我们将不胜感激。

在返回PartialViewResult时,更新主窗体以显示自定义验证消息

AddHIVTest()控制器方法中,添加ModelState错误几乎没有意义。这些是为在与窗体关联的ValidationSummary()ValidationMessageFor()帮助程序中使用而设计的,但关联的分部没有窗体。相反,您可以将错误消息添加到视图模型或ViewBag属性中,例如

catch (Exception ex)
{
  ViewBag.ErrorMessage = ex.ToString();
}

然后可以在_HIVTestCollection部分中渲染为(比如)

<div id="errormessage">@ViewBag.ErrorMessage</div>

然后,如果您想在主视图中与渲染分部的位置不同的位置显示该消息,请修改ajax函数,将<div>移动到新位置。假设主视图包含元素

<div id="errorcontainer"><div> // placeholder for the error message
.... // other elements
<div id="HIVTestCollection"><div> // placeholder for the partial

然后

$.ajax({
    url: '/HIVInformation/AddHIVTest/',
    type: 'post',
    data: dataToSend,
    success: function (partialViewReceived) {
        $('#HIVTestCollection').html(partialViewReceived);
        $('#errorcontainer').append($('#errormessage')); // move the message from the partial to the placeholder in the main view
    }
});

另一种选择是生成2个局部视图(其中一个有错误),并使用本答案中描述的技术将它们作为字符串返回(在JsonResult中)。