【问题标题】:MVC AJAX Return View if server-side validation fails如果服务器端验证失败,MVC AJAX 返回视图
【发布时间】:2017-10-13 18:05:05
【问题描述】:

我有一个搜索表单,它将进行一些客户端验证、调用服务器操作、进行一些服务器端验证,然后返回原始视图(带有模型状态错误)或搜索结果。

为了使这种方法起作用,我需要将视图呈现为字符串,并返回 Json 结果。 我可以用这个问题中的一个答案来做到这一点:Render a view as a string

但是,如果我必须实现自己的“RenderView”类型函数,这真的是最好的方法吗?或者是否有更好的设计决策来实现这种功能? 任何帮助将不胜感激。

下面列出了代码的抽象供参考;

控制器:

public ActionResult Index()
{
    return View(new SearchModel());
}

public ActionResult Search(SearchModel criteria)
{
    if (!ModelState.IsValid)
        return Json(new { HasErrors = true, Result = RenderViewToString("Index", criteria) });

    var results = {Do Search...};
    return PartialView("SearchResults", results);
}

查看:

@using(Html.BeginForm(...))
{
    {form fields...}
    {submit button...}
}
<div id="search-results"></div>

<script type="text/javascript">
    $(document).on("submit", "form", function(e) {
        if (!$(this).valid()) return false;

        e.preventDefault(); // Submit the form with ajax instead.
        $.ajax({
            url: this.action,
            type: this.method
            data: $(this).serialize(),
            success: function(data) {
                if (data.HasErrors) {
                    $(document).html(data.Result);
                }
                else {
                    $("#search-results").html(data);
                }
            }
        });
     });
</script>

【问题讨论】:

    标签: jquery ajax asp.net-mvc asp.net-mvc-5


    【解决方案1】:

    首先你需要这个 jquery 函数来在验证摘要中添加错误

    $.fn.addNewErrorMessage = function (message) {
        $(this).find('.validation-summary-valid').removeClass('validation-summary-valid')
            .addClass('validation-summary-errors');
        $(this).find(".validation-summary-errors ul").append("<li>" + message + "</li>");
    }
    

    然后您需要制作一个错误列表并将其作为 JSON 格式返回,就像此代码在运行中一样。

    if (!modelState.IsValid)
    {
        var errors = ModelState.ToDictionary(kvp => kvp.Key,
               kvp => kvp.Value.Errors
                          .Select(e => e.ErrorMessage).ToArray())
                          .Where(m => m.Value.Count() > 0);
         return Json(new {HasErrors = true,Errors = errors});
    }
    

    之后在 ajax 的成功函数中使用 addNewErrorMessage 函数来显示错误信息

    $.ajax({
            url: this.action,
            type: this.method
            data: $(this).serialize(),
            success: function(data) {
                if (data.HasErrors) {
                    for(int i; i<data.Errors.length)
                    {
                        $('form').addNewErrorMessage(data.Errors[i].Value);
                    }
                }
                else {
                    $("#search-results").html(data);
                }
            }
    

    【讨论】:

    • 有没有办法选择每个字段错误,并将其应用到各自的字段(而不是摘要)?如果我可以选择属性名称以及错误,那么我可以使用“data-valmsg-for”数据属性来选择并放置错误。
    • 没关系;我检查了 - 密钥具有属性名称。所以我应该能够完成这项工作。
    • 我认为您可以使用 data.Errors[i].Key 选择特定错误
    【解决方案2】:

    我已将 Kiyarash 的答案标记为正确,因为它让我走上了正确的道路。 这是我实际使用的: (请注意,这只会显示每个字段的最后一个错误 - 我将在其中添加一些逻辑,以便显示多个错误消息。

    if (!ModelState.IsValid)
    {
        return Json(new
        {
            HasErrors = true,
            Errors = ModelState.ToDictionary(
                ms => ms.Key,
                ms => ms.Value.Errors.Select(e => e.ErrorMessage).ToArray()
            ).Where(ms => ms.Value.Count() > 0)
        }, JsonRequestBehavior.AllowGet);
    }
    
    $.ajax({
        ...
        success: function(data) {
            if (data.HasErrors) {
                showErrorMessages(data.Errors, $("form"));
            }
            else {
                $("#search-results").html(data);
            }
        }
    });
    
    function showErrorMessages(errors, context) {
        $.each(errors, function (i, error) {
            $("[data-valmsg-for='" + error.Key + "']", context).text(error.Value)
                .removeClass("field-validation-valid")
                .addClass("field-validation-error");
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-16
      • 2022-08-16
      • 2014-02-22
      • 1970-01-01
      相关资源
      最近更新 更多