Проверка jQuery, ошибки ASP.NET MVC ModelState (Async POST) - PullRequest
22 голосов
/ 02 сентября 2011

Я занимаюсь разработкой веб-приложения с asp.net mvc 3, и у меня есть какая-то форма, которая POST выполняет асинхронное действие (через ajax). Это действие возвращает ViewModel с некоторыми аннотациями данных для его проверки. Проверка работает нормально, но когда валидаторы возвращают ошибку, я не знаю, как я могу вернуть ее, чтобы показать в моем представлении (потому что POST был сделан ajax).

Мои действия похожи на:

[HttpPost]
public ActionResult SaveCustomer(CustomerViewModel input) {
    if (!ModelState.IsValid) { // <-- business validation
        return Json(new { success = false, errors = ???});
    }
    // persist 
    return Json(new { success = true });
}

Как я могу показать эти ошибки с помощью jquery validate на мой взгляд? Если есть возможность опубликовать код для примера ... Я бы оценил это!

Спасибо, ребята!

Ответы [ 4 ]

49 голосов
/ 02 сентября 2011

Вместо отправки JSON в случае ошибки, я бы поместил форму внутри партиала, а затем действие контроллера вернуло этот партиал в случае ошибки.Проблема с JSON заключается в том, что вы могли бы на самом деле получать ошибки из ModelState с помощью LINQ, но это может быть PITA, чтобы показать их в представлении.

Итак:

<div id="myform">
    @Html.Partial("_MyForm")
</div>

изатем внутри _MyForm.cshtml:

@model CustomerViewModel
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.Foo)
    @Html.ValidationMessageFor(x => x.Foo)
    <br />
    @Html.EditorFor(x => x.Bar)
    @Html.ValidationMessageFor(x => x.Bar)
    <br />
    <input type="submit" value="OK" />
}

и действие контроллера станет:

[HttpPost]
public ActionResult SaveCustomer(CustomerViewModel model)
{
    if (!ModelState.IsValid)
    {
        return PartialView("_MyForm", model);
    }
    return Json(new { success = true });
}

, и последний шаг - AJAXify эта форма, которую можно сделать в отдельном файле javascript:

$(function () {
    $('#myform').delegate('form', 'submit', function () {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                if (result.success) { 
                    // We have a JSON object in case of success
                    alert('success');
                } else {
                    // We have the partial with errors in case of failure
                    // so all we have to do is update the DOM
                    $('#myform').html(result);
                }
            }
        });
        return false;
    });
});
15 голосов
/ 02 сентября 2011

Вы можете вернуть ошибки ModelState. Это не проверено, но что-то вроде этого должно работать.

return Json(new
            {
                success = false,
                errors = ModelState.Keys.SelectMany(k => ModelState[k].Errors)
                                .Select(m => m.ErrorMessage).ToArray()
            });

Редактировать: чтобы отобразить ошибки в представлении, вы просто проверяете, были ли вы успешными, а если нет, переберите список ошибок и поместите их там, где вы видите свои ошибки.

if(!result.success) {
    for(var error in result.errors) {
        $('#errorMessages').append(error + '<br />');
    }
}

Я предпочитаю ответ Дарина для большинства проектов, но ваш потребитель не всегда может быть вашим собственным приложением, и в этом случае более целесообразно возвращать список ошибок, поскольку это позволит потребителю отображать ошибки так, как они захотят.

1 голос
/ 09 сентября 2018

Создание класса для представления ошибок ModelState для отдельных свойств.

public class ValidationError
{

    public string PropertyName = "";
    public string[] ErrorList = null;
}

Создание метода, который возвращает список ошибок ValidationErrors на основе ModelState

    public IEnumerable<ValidationError> GetModelStateErrors(ModelStateDictionary modelState)
    {
        var errors = (from m in modelState
                            where m.Value.Errors.Count() > 0
                            select
                               new ValidationError
                               {
                                   PropertyName = m.Key,
                                   ErrorList = (from msg in m.Value.Errors
                                                  select msg.ErrorMessage).ToArray()
                               })
                            .AsEnumerable();
        return errors;
    }

Затем в контроллере PostМетод do:

        if (!ModelState.IsValid)
        {
            return Json(new
            {
                errors = true,
                errorList = GetModelStateErrors(ModelState)
            }, JsonRequestBehavior.AllowGet);
        }

Вы можете создать JS-функции, которые перебирают список ошибок, возвращенный выше

$.ajax({
            cache: false,
            async: true,
            type: "POST",
            url: form.attr('action'),
            data: form.serialize(),
            success: function (data) {
                if (data.errors) {
                    displayValidationErrors(data.errorList);
                 }
            },
        error: function (result) {
            console.log("Error");
        }

    });

function displayValidationErrors(errors) {
    $.each(errors, function (idx, validationError) {

        $("span[data-valmsg-for='" + validationError.PropertyName + "']").text(validationError. ErrorList[0]);

    });
}

В приведенном выше примере я получаю только первое сообщение об ошибке из ErrorList».Вы можете создать дополнительный цикл для получения всех сообщений и добавления их к вашему периоду проверки.

0 голосов
/ 16 января 2019

Попробуйте этот код.Это простое решение вашей проблемы.Он объединит все ошибки состояния модели в одну строку.

[HttpPost]
    public ActionResult SaveCustomer(CustomerViewModel input) {
        if (!ModelState.IsValid) { // <-- business validation
            return Json(new { success = false, errors = string.Join("; ", ModelState.Values
                                            .SelectMany(x => x.Errors)
                                            .Select(x => x.ErrorMessage));});
        }
        // persist 
        return Json(new { success = true });
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...