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

时间:2022-12-09 13:45:49

I have a search form, which will do some client side validation, call the server action, do some server side validation, and then return either the original view (with the modelstate errors) OR the search results.

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

For this approach to work, i would need to render the view to a string, and return a Json result. I could probably do that with one of the answers in this question: Render a view as a string

对于这种方法,我需要将视图呈现为字符串,并返回Json结果。我可以用这个问题中的一个答案来做:将视图呈现为字符串

However, if i'm having to implement my own 'RenderView' type function, is this really the best way to do this? Or is there a better design decision for implementing this kind of functionality? Any help would be greatly appreciated.

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

An abstraction of the code is listed below for reference;

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

Controller:

控制器:

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

View:

观点:

@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 个解决方案

#1


1  

First of all you need this jquery function to add error in validation summary

首先,需要这个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>");
}

Then you need make a list of error and return it as a JSON format like this code in action.

然后,您需要创建一个错误列表,并将其作为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});
}

After that in success function in ajax use addNewErrorMessage function to show error messages

在成功之后,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);
            }
        }

#2


1  

I've marked Kiyarash's answer as correct, as it put me on the right track. Here is what i actually used though: (Please note that this will only show the last error for each field - I will be adding some logic into it, so that it shows multiple error messages).

我把基雅拉什的答案标记为正确,因为它使我走上了正确的轨道。这里是我实际使用的:(请注意,这将只显示每个字段的最后一个错误——我将在其中添加一些逻辑,以便它显示多个错误消息)。

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

#1


1  

First of all you need this jquery function to add error in validation summary

首先,需要这个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>");
}

Then you need make a list of error and return it as a JSON format like this code in action.

然后,您需要创建一个错误列表,并将其作为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});
}

After that in success function in ajax use addNewErrorMessage function to show error messages

在成功之后,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);
            }
        }

#2


1  

I've marked Kiyarash's answer as correct, as it put me on the right track. Here is what i actually used though: (Please note that this will only show the last error for each field - I will be adding some logic into it, so that it shows multiple error messages).

我把基雅拉什的答案标记为正确,因为它使我走上了正确的轨道。这里是我实际使用的:(请注意,这将只显示每个字段的最后一个错误——我将在其中添加一些逻辑,以便它显示多个错误消息)。

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