使用jQuery Ajax的ASP.NET MVCvalidation?

我有这样简单的ASP.NET MVC操作:

public ActionResult Edit(EditPostViewModel data) { } 

EditPostViewModel具有这样的validation属性:

 [Display(Name = "...", Description = "...")] [StringLength(100, MinimumLength = 3, ErrorMessage = "...")] [Required()] public string Title { get; set; } 

在视图中,我使用以下帮助程序:

  @Html.LabelFor(Model => Model.EditPostViewModel.Title, true) @Html.TextBoxFor(Model => Model.EditPostViewModel.Title, new { @class = "tb1", @Style = "width:400px;" }) 

如果我在窗体上进行提交,那么这个文本框被放置在一个validation中将首先在客户端上完成,然后在服务( ModelState.IsValid )上完成。

现在我有几个问题:

  1. 可以用jQuery ajax提交吗? 我正在做的只是删除表单,并点击提交buttonJavaScript将收集数据,然后运行$.ajax

  2. 请问服务器端的ModelState.IsValid工作?

  3. 如何将validation问题转发回客户端,并将其作为使用构buildintvalidation( @Html.ValidationSummary(true) )进行展示?

Ajax调用示例:

 function SendPost(actionPath) { $.ajax({ url: actionPath, type: 'POST', dataType: 'json', data: { Text: $('#EditPostViewModel_Text').val(), Title: $('#EditPostViewModel_Title').val() }, success: function (data) { alert('success'); }, error: function () { alert('error'); } }); } 

编辑1:

包括在页面上:

 <script src="/Scripts/jquery-1.7.1.min.js"></script> <script src="/Scripts/jquery.validate.min.js"></script> <script src="/Scripts/jquery.validate.unobtrusive.min.js"></script> 

客户端

使用jQuery.validate库应该是非常简单的设置。

Web.config文件中指定以下设置:

 <appSettings> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings> 

当你build立你的观点时,你可以定义如下的东西:

 @Html.LabelFor(Model => Model.EditPostViewModel.Title, true) @Html.TextBoxFor(Model => Model.EditPostViewModel.Title, new { @class = "tb1", @Style = "width:400px;" }) @Html.ValidationMessageFor(Model => Model.EditPostViewModel.Title) 

注:这些需要在表单元素中定义

那么你将需要包括以下库:

 <script src='@Url.Content("~/Scripts/jquery.validate.js")' type='text/javascript'></script> <script src='@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")' type='text/javascript'></script> 

这应该能够设置你的客户端validation

资源

服务器端

注:这仅用于jQuery.validation库之上的附加服务器端validation

也许像这样的东西可以帮助:

 [ValidateAjax] public JsonResult Edit(EditPostViewModel data) { //Save data return Json(new { Success = true } ); } 

其中ValidateAjax是一个定义如下的属性:

 public class ValidateAjaxAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.HttpContext.Request.IsAjaxRequest()) return; var modelState = filterContext.Controller.ViewData.ModelState; if (!modelState.IsValid) { var errorModel = from x in modelState.Keys where modelState[x].Errors.Count > 0 select new { key = x, errors = modelState[x].Errors. Select(y => y.ErrorMessage). ToArray() }; filterContext.Result = new JsonResult() { Data = errorModel }; filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.BadRequest; } } } 

这样做是返回一个指定所有模型错误的JSON对象。

示例响应将是

 [{ "key":"Name", "errors":["The Name field is required."] }, { "key":"Description", "errors":["The Description field is required."] }] 

这将返回到$.ajax调用的error handlingcallback

你可以通过返回的数据循环来根据返回的键设置错误消息(我认为像$('input[name="' + err.key + '"]')会find你的input元素

你应该做的是序列化你的表单数据,并将其发送给控制器操作。 ASP.NET MVC将使用MVC模型绑定function将表单数据绑定到EditPostViewModel对象(您的动作方法参数)。

您可以在客户端validation您的表单,如果一切正常,则将数据发送到服务器。 valid()方法将派上用场。

 $(function () { $("#yourSubmitButtonID").click(function (e) { e.preventDefault(); var _this = $(this); var _form = _this.closest("form"); var isvalid = _form .valid(); // Tells whether the form is valid if (isvalid) { $.post(_form.attr("action"), _form.serialize(), function (data) { //check the result and do whatever you want }) } }); }); 

这是一个相当简单的解决scheme:

在控制器中,我们返回像这样的错误:

 if (!ModelState.IsValid) { return Json(new { success = false, errors = ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage).ToList() }, JsonRequestBehavior.AllowGet); } 

以下是一些客户端脚本:

 function displayValidationErrors(errors) { var $ul = $('div.validation-summary-valid.text-danger > ul'); $ul.empty(); $.each(errors, function (idx, errorMessage) { $ul.append('<li>' + errorMessage + '</li>'); }); } 

这就是我们通过Ajax处理的方式:

 $.ajax({ cache: false, async: true, type: "POST", url: form.attr('action'), data: form.serialize(), success: function (data) { var isSuccessful = (data['success']); if (isSuccessful) { $('#partial-container-steps').html(data['view']); initializePage(); } else { var errors = data['errors']; displayValidationErrors(errors); } } }); 

另外,我通过以下方式通过ajax渲染部分视图:

 var view = this.RenderRazorViewToString(partialUrl, viewModel); return Json(new { success = true, view }, JsonRequestBehavior.AllowGet); 

RenderRazorViewToString方法:

 public string RenderRazorViewToString(string viewName, object model) { ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); return sw.GetStringBuilder().ToString(); } } 

你可以这样做:

编辑:考虑到你正在等待与dataType: 'json'的响应json dataType: 'json'

。净

 public JsonResult Edit(EditPostViewModel data) { if(ModelState.IsValid) { // Save return Json(new { Ok = true } ); } return Json(new { Ok = false } ); } 

JS:

 success: function (data) { if (data.Ok) { alert('success'); } else { alert('problem'); } }, 

如果你需要,我也可以通过返回一个错误500来解释怎么做,并得到事件错误(ajax)中的错误。 但在你的情况下,这可能是一个select