将 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:11:07  来源:igfitidea点击:

Use ASP.NET MVC validation with jquery ajax?

jqueryajaxasp.net-mvcvalidation

提问by Ivy

I have simple ASP.NET MVC action like this :

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

public ActionResult Edit(EditPostViewModel data)
{

}

The EditPostViewModelhave 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 :

现在我有几个问题:

  1. 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.

  2. Will the server side ModelState.IsValidwork?

  3. How can I forward validation problem back to the client and present it as if Im using the build int validation(@Html.ValidationSummary(true))?

  1. 这可以与 jQuery ajax submit 一起使用吗?我正在做的只是删除表单,然后单击提交按钮,javascript 将收集数据,然后运行$.ajax.

  2. 服务器端会ModelState.IsValid工作吗?

  3. 我如何将验证问题转发回客户端并将其呈现为我使用构建 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.validatelibrary should be pretty simple to set up.

使用该jQuery.validate库应该很容易设置。

Specify the following settings in your Web.configfile:

在您的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.validationlibrary

注意:这仅用于jQuery.validation库顶部的额外服务器端验证

Perhaps something like this could help:

也许这样的事情会有所帮助:

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

Where ValidateAjaxis 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 $.ajaxcall

这将返回到您的错误处理回调$.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 EditPostViewModelobject( 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 jsonwith dataType: 'json')

编辑:考虑到你在等待的响应jsondataType: '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) 中获取错误。但在你的情况下,这可能是一个选择