如果服务器端验证失败,MVC AJAX返回视图

时间:2017-05-15 03:44:43

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

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

要使这种方法起作用,我需要将视图呈现为字符串,并返回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>

2 个答案:

答案 0 :(得分:2)

首先,您需要此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);
            }
        }

答案 1 :(得分: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");
    });
}