将 ASP.NET MVC 验证与 jquery ajax 一起使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14005773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use ASP.NET MVC validation with jquery ajax?
提问by Ivy
I have simple ASP.NET MVC action like this :
我有这样的简单 ASP.NET MVC 操作:
public ActionResult Edit(EditPostViewModel data)
{
}
The EditPostViewModel
have validation attributes like this :
该EditPostViewModel
有这样的验证特性:
[Display(Name = "...", Description = "...")]
[StringLength(100, MinimumLength = 3, ErrorMessage = "...")]
[Required()]
public string Title { get; set; }
In the view I am using the following helpers :
在视图中,我使用了以下助手:
@Html.LabelFor(Model => Model.EditPostViewModel.Title, true)
@Html.TextBoxFor(Model => Model.EditPostViewModel.Title,
new { @class = "tb1", @Style = "width:400px;" })
If I do a submit on a form that this textbox is placed in a validation will be done first on client and then on service(ModelState.IsValid
).
如果我在表单上提交此文本框放置在验证中的表单,则将首先在客户端上完成,然后在服务(ModelState.IsValid
)上完成。
Now I got a couple of questions :
现在我有几个问题:
Can this be used with jQuery ajax submit instead? What I am doing is simply remove the form and on clicking the submit button a javascript will gather data and then run the
$.ajax
.Will the server side
ModelState.IsValid
work?How can I forward validation problem back to the client and present it as if Im using the build int validation(
@Html.ValidationSummary(true)
)?
这可以与 jQuery ajax submit 一起使用吗?我正在做的只是删除表单,然后单击提交按钮,javascript 将收集数据,然后运行
$.ajax
.服务器端会
ModelState.IsValid
工作吗?我如何将验证问题转发回客户端并将其呈现为我使用构建 int 验证(
@Html.ValidationSummary(true)
)?
Example of Ajax call :
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');
}
});
}
Edit 1:
编辑1:
Included on page :
包含在页面上:
<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>
回答by Andrew Burgess
Client Side
客户端
Using the jQuery.validate
library should be pretty simple to set up.
使用该jQuery.validate
库应该很容易设置。
Specify the following settings in your Web.config
file:
在您的Web.config
文件中指定以下设置:
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
When you build up your view, you would define things like this:
当你建立你的视图时,你会定义这样的东西:
@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)
NOTE:These need to be defined within a form element
注意:这些需要在表单元素中定义
Then you would need to include the following libraries:
然后你需要包含以下库:
<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>
This should be able to set you up for client side validation
这应该能够为您设置客户端验证
Resources
资源
Server Side
服务器端
NOTE:This is only for additional server side validation on top of jQuery.validation
library
注意:这仅用于jQuery.validation
库顶部的额外服务器端验证
Perhaps something like this could help:
也许这样的事情会有所帮助:
[ValidateAjax]
public JsonResult Edit(EditPostViewModel data)
{
//Save data
return Json(new { Success = true } );
}
Where ValidateAjax
is an attribute defined as:
当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;
}
}
}
What this does is return a JSON object specifying all of your model errors.
这样做是返回一个 JSON 对象,指定您的所有模型错误。
Example response would be
示例响应将是
[{
"key":"Name",
"errors":["The Name field is required."]
},
{
"key":"Description",
"errors":["The Description field is required."]
}]
This would be returned to your error handling callback of the $.ajax
call
这将返回到您的错误处理回调$.ajax
调用
You can loop through the returned data to set the error messages as needed based on the Keys returned (I think something like $('input[name="' + err.key + '"]')
would find your input element
您可以根据返回的键遍历返回的数据以根据需要设置错误消息(我认为类似的东西$('input[name="' + err.key + '"]')
会找到您的输入元素
回答by Shyju
What you should do is to serialize your form data and send it to the controller action. ASP.NET MVC will bind the form data to the EditPostViewModel
object( your action method parameter), using MVC model binding feature.
您应该做的是序列化表单数据并将其发送到控制器操作。ASP.NET MVC 将EditPostViewModel
使用 MVC 模型绑定功能将表单数据绑定到对象(您的操作方法参数)。
You can validate your form at client side and if everything is fine, send the data to server. The valid()
method will come in handy.
您可以在客户端验证您的表单,如果一切正常,将数据发送到服务器。该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
})
}
});
});
回答by Alex Herman
Here's a rather simple solution:
这是一个相当简单的解决方案:
In the controller we return our errors like this:
在控制器中,我们像这样返回错误:
if (!ModelState.IsValid)
{
return Json(new { success = false, errors = ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage).ToList() }, JsonRequestBehavior.AllowGet);
}
Here's some of the client script:
这是一些客户端脚本:
function displayValidationErrors(errors)
{
var $ul = $('div.validation-summary-valid.text-danger > ul');
$ul.empty();
$.each(errors, function (idx, errorMessage) {
$ul.append('<li>' + errorMessage + '</li>');
});
}
That's how we handle it via ajax:
这就是我们通过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);
}
}
});
Also, I render partial views via ajax in the following way:
另外,我通过以下方式通过ajax呈现部分视图:
var view = this.RenderRazorViewToString(partialUrl, viewModel);
return Json(new { success = true, view }, JsonRequestBehavior.AllowGet);
RenderRazorViewToString method:
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();
}
}
回答by Manprit Singh Sahota
Added some more logic to solution provided by @Andrew Burgess. Here is the full solution:
为@Andrew Burgess 提供的解决方案添加了更多逻辑。这是完整的解决方案:
Created a action filter to get errors for ajax request:
创建了一个动作过滤器来获取 ajax 请求的错误:
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;
}
}
}
Added the filter to my controller method as:
将过滤器添加到我的控制器方法中:
[HttpPost]
// this line is important
[ValidateAjax]
public ActionResult AddUpdateData(MyModel model)
{
return Json(new { status = (result == 1 ? true : false), message = message }, JsonRequestBehavior.AllowGet);
}
Added a common script for jquery validation:
添加了用于 jquery 验证的通用脚本:
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);
}
Finally added the error javascript method to my Ajax Begin form:
最后在我的 Ajax Begin 表单中添加了错误 javascript 方法:
@model My.Model.MyModel
@using (Ajax.BeginForm("AddUpdateData", "Home", new AjaxOptions { HttpMethod = "POST", OnFailure="onAjaxFormError" }))
{
}
回答by andres descalzo
You can do it this way:
你可以这样做:
(Edit:Considering that you're waiting for a response json
with dataType: 'json'
)
(编辑:考虑到你在等待的响应json
与dataType: 'json'
)
.NET
。网
public JsonResult Edit(EditPostViewModel data)
{
if(ModelState.IsValid)
{
// Save
return Json(new { Ok = true } );
}
return Json(new { Ok = false } );
}
JS:
JS:
success: function (data) {
if (data.Ok) {
alert('success');
}
else {
alert('problem');
}
},
If you need I can also explain how to do it by returning a error 500, and get the error in the event error (ajax). But in your case this may be an option
如果您需要,我还可以通过返回错误 500 来解释如何执行此操作,并在事件错误 (ajax) 中获取错误。但在你的情况下,这可能是一个选择