2

私はMVC5、クライアントとサーバーの検証を組み合わせて使用​​しています。この特定の問題については、リモート検証を使用しています。

Razorview : _

<div id="studentStatus" name="studentStatus">
@using (Html.BeginForm("StudentStatus", "StudentStatus", FormMethod.Post, new { id = "studentStatusForm", data_timer = 240000 }))
{
    @Html.HiddenFor(x => x.CurrentStudentSepId, new { @class = "hideMe" })
    <div class="row">
        <h2 class="col-md-12 topSectionHeader">
            @StaffPortalResources.Section_StudentStatus
            <span class="savedStatus"></span>
        </h2>
    </div>
    <span class="errorNotification"></span>
    <div class="questionGroup form-group">
        <div class="row margin-btm-sm">
            <div class="col-md-4">
                @Html.LabelFor(x => x.StudentStatusId)
                @if (Model.IsReadOnly)
                {
                    <div>@Html.DisplayFor(x => x.StudentStatusId)</div>
                    @Html.HiddenFor(x => x.StudentStatusId)
                }
                else
                {
                    @Html.CustomComboBoxFor(x => x.StudentStatusId, (new { @class = "statusChangeValidationHandler", data_action = "GetStudentEditableStatuses", data_controller = "Lookup" }))
                }

                @Html.ValidationMessageFor(x => x.StudentStatusId)
            </div>
 }

モデル:

public sealed class StudentStatusSectionViewModel : SectionViewModel
{
    [Display(Name = "Status", ResourceType = typeof(StaffPortalResources))]
    [SelectMustExist(true, ErrorMessageResourceType = typeof (StaffPortalResources), ErrorMessageResourceName = "StudentStatus_InvalidSelection")]
    [Remote("ValidateStudentStatus", "StudentStatus", AdditionalFields = "CurrentStudentSepId")]
    public string StudentStatusId { get; set; }

    public bool DoNotReenroll { get; set; }
}

コントローラー:

public JsonResult ValidateStudentStatus(StudentStatusSectionViewModel model)
{
    var errors = _studentStatusSectionAdapter.ValidateStudentStatus(model.CurrentStudentSepId, model.StudentStatusId);
    if (errors != null && errors.Any())
    {
        var currentStatus = _studentStatusSectionAdapter.Get(model.CurrentStudentSepId).StudentStatusId;
        Response.AddHeader("status", currentStatus);
        return Json(string.Join("</br>", errors), JsonRequestBehavior.AllowGet);
    }

    return Json(true, JsonRequestBehavior.AllowGet);
}

リモート検証 .complete() 関数:

scope.initializeStudentStatusDropdown = function() {
    var $element = $('#studentStatusForm').find('input.statusChangeValidationHandler[data-role="combobox"]');

    $element.rules().remote.complete = function (xhr) {
        if (xhr.responseText !== 'true')
            window.Registration.StudentStatus.fixStudentStatusDropdown($element, xhr.getResponseHeader);
    }
}

scope.fixStudentStatusDropdown = function($element,responseHeader) {
    $element.kVal(responseHeader('status'));
}

変更イベントの検証を配線するために使用される jquery:

scope.initializeAutoSave = function (form, callBack) {
    var $form = $(form);
    $form.on("change", "input:not(.ignoreAutoSave)", queueForm);
    $form.on("change", "textarea:not(.ignoreAutoSave)", queueForm);
    window.Validation.initializeValidator($form);
    callBacks[$form.attr('id')] = callBack || function() {};
}

queueForm メソッド:

function queueForm(e) {
    if ($(e.target).valid()) {
        var $form = $(e.target).closest("form");
        var timer = $form.data("timer");
        autoSaveQueue[$form.attr("id")] = { $form: $form, timer: timer, attempt: 0 };
    }
}

ドロップダウンの値を変更した後にコードをトレースすると、change イベントが発生し、queueForm 関数が呼び出されます。valid()リモート検証が行われる前に、呼び出しは true と評価されます。

'if ($(e.target).valid())' 行をまたぐと、true と評価されて if ブロックに入ります。ValidateStudentStatus次に、コントローラーのリモート機能にジャンプします。

ここで何か間違ったことをしましたか?リモート検証の仕組みを誤解していますか?

洞察や助けをいただければ幸いです。

4

0 に答える 0