Подтвердить что ты не робот

ASP.NET MVC "Ajax.BeginForm" выполняет OnSuccess, хотя модель недействительна

У меня есть форма "отправить отзыв", которая использует "Ajax.BeginForm" для частичного отображения элементов формы. Событие OnSuccess запускается, даже если ModelState недействителен. Это нормально? Я ожидал, что смогу сделать несколько обратных передач, приводящих к недопустимой модели, а затем, когда модель будет действительна и ошибок нет, событие OnSuccess вызовет?

4b9b3361

Ответ 1

Я справляюсь с этой проблемой с довольно простой техникой javascript:

Сначала настройте свой OnSuccess следующим образом:

OnSuccess = "UpdateSuccessful(data)"

Затем ваша функция javascript выглядит следующим образом:

function UpdateSuccessful(data) {
    if (data.indexOf("field-validation-error") > -1) return;

    // Do your valid stuff here
}

Таким образом, вам не нужно связываться с контроллером, или, что более важно, ваш контроллер может вернуть Partial View с ошибками модели, не делая ничего странного, например:

    public ActionResult SaveDetails(Project model)
    {
        if (ModelState.IsValid)
        {
            model.SaveProject();
        }

        return PartialView("ProjectForm", model);
    }

И в вашем AjaxOptions:

UpdateTargetId = "FormContents"

Теперь просто убедитесь, что у вас есть div или что-то с id="FormContents" везде, где вы хотите, чтобы ваша форма отображалась.

Ответ 2

Это нормально?

Да, конечно. Если сервер отправляет HTTP 200, вызывается метод OnSuccess. Понятие правильности modelstate является только серверной. До тех пор, пока действие вашего контроллера вернет некоторое представление /partial/json/..., активируется OnSuccess. Если в действие вашего контроллера выбрано исключение, вместо OnSuccess будет запускаться OnError.

Итак, чтобы справиться с этим случаем, вы могли бы заставить ваше действие контроллера сделать что-то по строкам:

[HttpPost]
public ActionResult Process(MyViewModel model)
{
    if (!ModelState.IsValid)
    {
        return Json(new { success = false });
    }
    return Json(new { success = true });
}

а затем:

function success(result) {
    if (result.success) {
        // the model was valid
    } else {
        // the model was invalid
    }
}

Теперь в случае недопустимой модели вы можете показать сообщения об ошибках пользователю, обновив форму. То, что вы могли бы сделать в этом случае, - это разместить свою форму внутри частичного, а в случае недопустимого состояния модели вы вернете частичное представление из действия вашего контроллера и в случае успеха - json-объект. Поэтому в вашем обработчике успеха вы можете проверить:

function success(result) {
    if (result.success) {
        // the model was valid
    } else {
        // there were errors => show them
        $('#myform_container').html(result);
        // if you are using client side validation you might also need
        // to take a look at the following article
        // http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx
        // and reattach the client validators to the form as you are
        // refreshing its DOM contents here
    }
}

Ответ 3

Вы можете сделать следующее:

var OnSuccess = function() {
    if ($(".validation-summary-errors").length == 0) { 
        //Your javascript/jquery code goes here
    }
}

Ответ 4

Незначительное изменение ответа Луиса:

function OnSuccess() {
    if ($("span[class='field-validation-error']").length == 0) {
        alert("Target Platform saved Successfully.");
    }
}

Ответ 5

Я возвращаю неверный запрос вместо просмотра, чтобы гарантировать, что вызов ajax вернется по ошибке, а не по ошибке.

В xhr.statustext вы можете найти строку, написанную в неверном запросе, и правильно управлять событием onfail.

Сторона сервера:

if (!ModelState.IsValid)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Model not valid");
        }

Сторона клиента:

$.ajax({
        url: '',
        method: 'POST'            
       }).fail(function (xhr) {
           alert(xhr.statustext);
       });