jQueryvalidation,ASP.NET MVC ModelState错误(异步POST)
我正在使用asp.net mvc 3开发一个Web应用程序,我有一些表单可以POST到异步操作(通过ajax)。 此操作将返回带有一些数据注释的ViewModel以对其进行validation。 validation工作正常,但当validation器返回错误时,我不知道如何将其返回到我的视图中显示(因为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 }); }
如何在我的视图中使用jquery validate显示此错误? 如果可以发布一些代码进行抽样……我会认为这样!
多谢你们!
我不会在出现错误的情况下发送JSON,而是将表单放在partial中,然后让控制器操作在出错时返回此部分。 JSON的问题在于你实际上可以使用LINQ从ModelState中获取错误,但它可能是一个PITA来在视图上显示它们。
所以:
@Html.Partial("_MyForm")
然后在_MyForm.cshtml
里面:
@model CustomerViewModel @using (Html.BeginForm()) { @Html.EditorFor(x => x.Foo) @Html.ValidationMessageFor(x => x.Foo)
@Html.EditorFor(x => x.Bar) @Html.ValidationMessageFor(x => x.Bar)
}
并且控制器动作将变为:
[HttpPost] public ActionResult SaveCustomer(CustomerViewModel model) { if (!ModelState.IsValid) { return PartialView("_MyForm", model); } return Json(new { success = true }); }
最后一步是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; }); });
您可以返回ModelState错误。 这是未经测试的,但这样的事情应该有效。
return Json(new { success = false, errors = ModelState.Keys.SelectMany(k => ModelState[k].Errors) .Select(m => m.ErrorMessage).ToArray() });
编辑:要在视图中显示错误,您只需检查是否成功,如果没有,则迭代错误列表并将它们放在显示错误的位置。
if(!result.success) { for(var error in result.errors) { $('#errorMessages').append(error + '
'); } }
我更喜欢Darin对大多数项目的回答,但您的消费者可能并不总是您自己的应用程序,在这种情况下返回错误列表更合适,因为它允许消费者显示他们想要的错误。
创建一个类来表示各个属性的ModelState错误。
public class ValidationError { public string PropertyName = ""; public string[] ErrorList = null; }
创建一个方法,该方法根据ModelState返回ValidationErrors列表
public IEnumerable 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; }
然后在你的控制器Post方法做:
if (!ModelState.IsValid) { return Json(new { errors = true, errorList = GetModelStateErrors(ModelState) }, JsonRequestBehavior.AllowGet); }
您可以创建循环遍历上面返回的错误列表的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]); }); }
在上面的示例中,我只从’ErrorList’获取第一条错误消息。 您可以创建一个额外的循环来获取所有消息并附加到validation范围。