124

私はこのような単純なASP.NETMVCアクションを持っています:

public ActionResult Edit(EditPostViewModel data)
{

}

次のEditPostViewModelような検証属性があります。

[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;" })

このテキストボックスが検証に配置されているフォームで送信を行うと、最初にクライアントで実行され、次にservice(ModelState.IsValid)で実行されます。

今、私はいくつかの質問を受けました:

  1. 代わりに、これをjQuery ajax submitで使用できますか?私がしているのは、フォームを削除し、送信ボタンをクリックすると、JavaScriptがデータを収集してからを実行すること$.ajaxです。

  2. サーバー側はModelState.IsValid機能しますか?

  3. 検証の問題をクライアントに転送して、build int validate(@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>
4

5 に答える 5

159

クライアント側

ライブラリを使用すると、jQuery.validateセットアップが非常に簡単になります。

Web.configファイルで次の設定を指定します。

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

ビューを構築するときは、次のように定義します。

@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>

これにより、クライアント側の検証をセットアップできるはずです

資力

サーバ側

注:jQuery.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これは、呼び出しのエラー処理コールバックに返されます

返されたデータをループして、返されたキーに基づいて必要に応じてエラーメッセージを設定$('input[name="' + err.key + '"]')できます(入力要素を見つけるようなものだと思います

于 2012-12-31T21:20:01.503 に答える
41

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.

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.

$(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
           })
        }

    });

});
于 2012-12-27T21:33:44.433 に答える
10

これはかなり単純な解決策です:

コントローラーでは、次のようにエラーを返します。

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();
        }
    }
于 2016-05-24T09:24:07.473 に答える
5

@Andrew Burgess が提供するソリューションにさらにロジックを追加しました。完全なソリューションは次のとおりです。

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;
            }
        }
    }

次のようにフィルターをコントローラーメソッドに追加しました。

[HttpPost]
// this line is important
[ValidateAjax]
public ActionResult AddUpdateData(MyModel model)
{
    return Json(new { status = (result == 1 ? true : false), message = message }, JsonRequestBehavior.AllowGet);
}

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);
}

最後に、エラー JavaScript メソッドを Ajax Begin フォームに追加しました。

@model My.Model.MyModel
@using (Ajax.BeginForm("AddUpdateData", "Home", new AjaxOptions { HttpMethod = "POST", OnFailure="onAjaxFormError" }))
{
}
于 2018-04-12T13:21:44.187 に答える
1

次の方法で実行できます。

編集: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) でエラーを取得することもできます。しかし、あなたの場合、これはオプションかもしれません

于 2012-12-22T20:20:05.283 に答える