使用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
)上完成。
现在我有几个问题:
-
可以用jQuery ajax提交吗? 我正在做的只是删除表单,并点击提交buttonJavaScript将收集数据,然后运行
$.ajax
。 -
请问服务器端的
ModelState.IsValid
工作? -
如何将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