Use ASP.NET MVC validation with jquery ajax?
我有这样简单的ASP.NET MVC动作:
1 2 3 4 | public ActionResult Edit(EditPostViewModel data) { } |
1 2 3 4 | [Display(Name ="...", Description ="...")] [StringLength(100, MinimumLength = 3, ErrorMessage ="...")] [Required()] public string Title { get; set; } |
在视图中,我使用以下帮助程序:
1 2 3 4 | @Html.LabelFor(Model => Model.EditPostViewModel.Title, true) @Html.TextBoxFor(Model => Model.EditPostViewModel.Title, new { @class ="tb1", @Style ="width:400px;" }) |
如果我在表单上提交此文本框放在验证中,将首先在客户端上进行,然后在服务上进行(
现在我有几个问题:
这可以与jQuery ajax提交一起使用吗? 我正在做的只是删除表单,单击提交按钮,javascript将收集数据,然后运行
服务器端
如何将验证问题转发回客户端并将其呈现为使用build int validation(
Ajax调用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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:
包含在页面上:
1 2 3 | <script src="/Scripts/jquery-1.7.1.min.js"> <script src="/Scripts/jquery.validate.min.js"> <script src="/Scripts/jquery.validate.unobtrusive.min.js"> |
客户端
使用
在
1 | </appSettings> |
构建视图时,您可以定义以下内容:
1 2 3 4 | @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) |
注意:这些需要在表单元素中定义
然后,您需要包含以下库:
1 2 | <script src='@Url.Content("~/Scripts/jquery.validate.js")' type='text/javascript'> <script src='@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")' type='text/javascript'> |
这应该可以为您设置客户端验证
资源
- http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvccustomvalidation_topic5.aspx
服务器端
注意:这仅适用于
也许这样的事情可能有所帮助:
1 2 3 4 5 6 | [ValidateAjax] public JsonResult Edit(EditPostViewModel data) { //Save data return Json(new { Success = true } ); } |
其中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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对象,指定所有模型错误。
示例响应将是
1 2 3 4 5 6 7 8 | [{ "key":"Name", "errors":["The Name field is required."] }, { "key":"Description", "errors":["The Description field is required."] }] |
这将返回到
您可以根据返回的键循环返回的数据以根据需要设置错误消息(我认为像
您应该做的是序列化表单数据并将其发送到控制器操作。 ASP.NET MVC将使用MVC模型绑定功能将表单数据绑定到
您可以在客户端验证表单,如果一切正常,请将数据发送到服务器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | $(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 }) } }); }); |
这是一个相当简单的解决方案:
在控制器中,我们返回如下错误:
1 2 3 4 | if (!ModelState.IsValid) { return Json(new { success = false, errors = ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage).ToList() }, JsonRequestBehavior.AllowGet); } |
这是一些客户端脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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处理它的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | $.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以下列方式呈现部分视图:
1 2 | var view = this.RenderRazorViewToString(partialUrl, viewModel); return Json(new { success = true, view }, JsonRequestBehavior.AllowGet); |
RenderRazorViewToString方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(); } } |
为@Andrew Burgess提供的解决方案增加了一些逻辑。这是完整的解决方案:
创建了一个动作过滤器来获取ajax请求的错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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; } } } |
将过滤器添加到我的控制器方法中:
1 2 3 4 5 6 7 | [HttpPost] // this line is important [ValidateAjax] public ActionResult AddUpdateData(MyModel model) { return Json(new { status = (result == 1 ? true : false), message = message }, JsonRequestBehavior.AllowGet); } |
添加了jquery验证的通用脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | function onAjaxFormError(data) { var form = this; var errorResponse = data.responseJSON; $.each(errorResponse, function (index, value) { // Element highlight var element = $(form).find('#' + value.key); element = element[0]; highLightError(element, 'input-validation-error'); // Error message var validationMessageElement = $('span[data-valmsg-for="' + value.key + '"]'); validationMessageElement.removeClass('field-validation-valid'); validationMessageElement.addClass('field-validation-error'); validationMessageElement.text(value.errors[0]); }); } $.validator.setDefaults({ ignore: [], highlight: highLightError, unhighlight: unhighlightError }); var highLightError = function(element, errorClass) { element = $(element); element.addClass(errorClass); } var unhighLightError = function(element, errorClass) { element = $(element); element.removeClass(errorClass); } |
最后将错误的javascript方法添加到我的Ajax Begin表单中:
1 2 3 4 | @model My.Model.MyModel @using (Ajax.BeginForm("AddUpdateData","Home", new AjaxOptions { HttpMethod ="POST", OnFailure="onAjaxFormError" })) { } |
你可以这样做:
(编辑:考虑到您正在等待
。净
1 2 3 4 5 6 7 8 9 10 | public JsonResult Edit(EditPostViewModel data) { if(ModelState.IsValid) { // Save return Json(new { Ok = true } ); } return Json(new { Ok = false } ); } |
JS:
1 2 3 4 5 6 7 8 | success: function (data) { if (data.Ok) { alert('success'); } else { alert('problem'); } }, |
如果您需要,我还可以通过返回错误500解释如何执行此操作,并在事件错误(ajax)中获取错误。但在你的情况下,这可能是一个选择