jQuery验证,ASP.NET MVC ModelState错误(异步POST)

Fel*_*ani 23 asp.net-mvc jquery jquery-validate

我正在使用asp.net mvc 3开发一个Web应用程序,我有一些表单可以POST到异步操作(通过ajax).此操作将返回带有一些数据注释的ViewModel以对其进行验证.验证工作正常但是当验证器返回错误时我不知道如何将其返回以在我的视图中显示(因为POST是由ajax制作的).

我的行为是这样的:

[HttpPost]
public ActionResult SaveCustomer(CustomerViewModel input) {
    if (!ModelState.IsValid) { // <-- business validation
        return Json(new { success = false, errors = ???});
    }
    // persist 
    return Json(new { success = true });
}
Run Code Online (Sandbox Code Playgroud)

如何在我的视图中使用jquery validate显示此错误?如果可以发布一些代码进行抽样......我会认为这样!

多谢你们!

Dar*_*rov 51

我不会在出现错误的情况下发送JSON,而是将表单置于部分内部,然后让控制器操作在发生错误时返回此部分.JSON的问题在于你实际上可以使用LINQ从ModelState中获取错误,但它可能是一个PITA来在视图上显示它们.

所以:

<div id="myform">
    @Html.Partial("_MyForm")
</div>
Run Code Online (Sandbox Code Playgroud)

然后在里面_MyForm.cshtml:

@model CustomerViewModel
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.Foo)
    @Html.ValidationMessageFor(x => x.Foo)
    <br />
    @Html.EditorFor(x => x.Bar)
    @Html.ValidationMessageFor(x => x.Bar)
    <br />
    <input type="submit" value="OK" />
}
Run Code Online (Sandbox Code Playgroud)

并且控制器动作将变为:

[HttpPost]
public ActionResult SaveCustomer(CustomerViewModel model)
{
    if (!ModelState.IsValid)
    {
        return PartialView("_MyForm", model);
    }
    return Json(new { success = true });
}
Run Code Online (Sandbox Code Playgroud)

最后一步是AJAXify这个表单,可以在一个单独的javascript文件中完成:

$(function () {
    $('#myform').delegate('form', 'submit', function () {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                if (result.success) { 
                    // We have a JSON object in case of success
                    alert('success');
                } else {
                    // We have the partial with errors in case of failure
                    // so all we have to do is update the DOM
                    $('#myform').html(result);
                }
            }
        });
        return false;
    });
});
Run Code Online (Sandbox Code Playgroud)

  • 太好了,希望我能给您更多的票! (2认同)

Tim*_*ple 15

您可以返回ModelState错误.这是未经测试的,但这样的事情应该有效.

return Json(new
            {
                success = false,
                errors = ModelState.Keys.SelectMany(k => ModelState[k].Errors)
                                .Select(m => m.ErrorMessage).ToArray()
            });
Run Code Online (Sandbox Code Playgroud)

编辑:要在视图中显示错误,您只需检查是否成功,如果没有,则迭代错误列表并将它们放在显示错误的位置.

if(!result.success) {
    for(var error in result.errors) {
        $('#errorMessages').append(error + '<br />');
    }
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢Darin对大多数项目的回答,但您的消费者可能并不总是您自己的应用程序,在这种情况下返回错误列表更合适,因为它允许消费者显示他们想要的错误.


Asa*_*aad 8

创建一个类来表示各个属性的 ModelState 错误。

public class ValidationError
{

    public string PropertyName = "";
    public string[] ErrorList = null;
}
Run Code Online (Sandbox Code Playgroud)

创建一个方法,该方法返回基于 ModelState 的 ValidationErrors 列表

    public IEnumerable<ValidationError> GetModelStateErrors(ModelStateDictionary modelState)
    {
        var errors = (from m in modelState
                            where m.Value.Errors.Count() > 0
                            select
                               new ValidationError
                               {
                                   PropertyName = m.Key,
                                   ErrorList = (from msg in m.Value.Errors
                                                  select msg.ErrorMessage).ToArray()
                               })
                            .AsEnumerable();
        return errors;
    }
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器 Post 方法中执行以下操作:

        if (!ModelState.IsValid)
        {
            return Json(new
            {
                errors = true,
                errorList = GetModelStateErrors(ModelState)
            }, JsonRequestBehavior.AllowGet);
        }
Run Code Online (Sandbox Code Playgroud)

您可以创建一个 JS 函数来循环上面返回的错误列表

$.ajax({
            cache: false,
            async: true,
            type: "POST",
            url: form.attr('action'),
            data: form.serialize(),
            success: function (data) {
                if (data.errors) {
                    displayValidationErrors(data.errorList);
                 }
            },
        error: function (result) {
            console.log("Error");
        }

    });

function displayValidationErrors(errors) {
    $.each(errors, function (idx, validationError) {

        $("span[data-valmsg-for='" + validationError.PropertyName + "']").text(validationError. ErrorList[0]);

    });
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我仅从“ErrorList”获取第一条错误消息。您可以创建一个额外的循环来获取所有消息并附加到您的验证范围。