Ajax.BeginForm всегда запускает метод OnSuccess, даже если данные неверны

Я пытаюсь отправить форму действию контроллера и обработать ответ на основе OnSuccess или OnFailure. Проблема в том, что даже если данные недействительны и я не прошел тест ModelState.IsValid, вызывается метод OnSuccess. Следует вызвать метод OnFailure.

Мой взгляд:

@using (Ajax.BeginForm("UpdateCategory", "Home", null, new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "categoryForm", OnSuccess = "alert('success');", OnFailure = "alert('failure');" }, new { id = "formEditCategory" }))
{
    @Html.ValidationSummary(true)

    @Html.HiddenFor(model => model.CategoryID)

    <div>
        <div class="editor-label">
            @Html.LabelFor(model => model.CategoryName)
        </div>
        <div class="small-multiline-field">
            @Html.EditorFor(model => model.CategoryName)
        </div>
        <div class="validationMsg">
            @Html.ValidationMessageFor(model => model.CategoryName)
        </div>
    </div>
}

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

[HttpPost]
public ActionResult UpdateCategory(CategoryVM category)
{
    try
    {
        if (ModelState.IsValid)
        {
            var itemService = new ItemViewModels();
            itemService.UpdateCategory(category);
        }
    }
    catch (DataException)
    {
        //Log the error (add a variable name after DataException)
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
    }

    return PartialView("EditCategoryInfo", category);
}

Моя модель просмотра:

public class CategoryVM
{
    public int CategoryID { get; set; }

    [StringLength(75, ErrorMessage = "Category Name must be under 75 characters.")]
    [DataType(DataType.MultilineText)]
    [Display(Name = "Name")]
    public string CategoryName { get; set; }

    [StringLength(3800, ErrorMessage = "Category Description must be under 3800 characters.")]
    [DataType(DataType.MultilineText)]
    [Display(Name = "Description")]
    [AllowHtml]
    public string CategoryDesc { get; set; }

    [Display(Name = "Display on Web")]
    public bool DisplayOnWeb { get; set; }
}

Поэтому, если я ввожу строку в поле CategoryName, длина которой превышает 75 символов, я вижу, что форма не проходит тест ModelState.IsValid, и представление отправляется обратно с пометкой «Имя категории должно быть менее 75 символов». сообщение об ошибке. Но вместо запуска события OnFailure он запускает событие OnSuccess. Почему?

Заранее спасибо.


person BKahuna    schedule 05.12.2012    source источник


Ответы (3)


Поскольку вы перехватили исключение, вы возвращаете PartialView с кодом состояния HTTP 200. Вот почему срабатывает OnSuccess.

Вместо этого вы можете явно установить код ответа 400 (неверный запрос).

[HttpPost]
public ActionResult UpdateCategory(CategoryVM category)
{
    try
    {
        if (ModelState.IsValid)
        {
            var itemService = new ItemViewModels();
            itemService.UpdateCategory(category);
        }
    }
    catch (DataException)
    {
        //Log the error (add a variable name after DataException)
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
        Response.StatusCode = 400;
    }

    return PartialView("EditCategoryInfo", category);
}
person Jack    schedule 05.12.2012
comment
Я использовал HttpStatusCodeResult для возврата определенного кода в одном сценарии, который не работал в Firefox, потому что содержимое не возвращалось. Я переключился на использование Response.StatusCode, Response.StatusDescription и Content("&nbsp;"), и теперь все работает нормально. - person Seth; 11.09.2013
comment
Если вы установите для StatusCode значение ошибки, вы не получите ошибки проверки, и ваша страница может быть отправлена ​​на страницу глобальной ошибки. Это не то решение, которое мне бы хотелось. - person Don Rolling; 12.01.2017
comment
Сведения об ошибке (в вашем случае это ошибки проверки) будут возвращены как часть тела ответа вместе с кодом состояния. Установка кода состояния только сообщает вам, что есть проблема с запросом. Хотите ли вы отправить пользователя на глобальную страницу ошибок или отобразить сообщение об ошибке на существующей странице, это полностью зависит от вас. Вы можете контролировать это поведение через свой javascript. - person Jack; 20.02.2017

Метод OnSuccess вызывается, если сервер возвращает успешный HTTP-ответ, например. 200 OK, и если клиент успешно получает ответ и обновляет страницу (как описано в MSDN)

Вам решать, как обработать содержимое ответа.

person Lukas Kabrt    schedule 05.12.2012

С некоторыми дополнительными исследованиями (и с помощью Лукаса ниже) я обнаружил is-not-valid">this, что решает мою проблему.

person BKahuna    schedule 05.12.2012
comment
Что могло бы заставить этот ответ работать, так это то, что вы разместили решение, а не ссылку на решение. Просто совет. Я проголосовал за вас, потому что мне нравится решение, на которое вы ссылаетесь. - person Don Rolling; 12.01.2017