HTTP Post запрос от различных действий контроллера и ModelState - PullRequest
0 голосов
/ 13 февраля 2012

У меня странная потребность в приложении ASP.NET MVC 3, которое блокирует мой текущий прогресс. Вот случай:

У меня есть небольшая поисковая система для продуктов, и я отображаю эту поисковую систему на нескольких страницах. Этот SE отправляет HTTP-запрос POST к действию product контроллера search. Это хорошо, пока здесь.

Предположим, что я на home действии контроллера index (/ home / index) . Я делаю поиск и проверяю ModelState.IsValid. В результате это не действует. Итак, я должен вернуть это обратно с введенной моделью (чтобы пользователь не потерял значения) и ошибками состояния модели. Но когда я это сделал, у меня получился другой URL (/ product / search), как и ожидалось.

Если я сделаю перенаправление, я потеряю ModelState и не смогу отображать сообщения об ошибках.

У меня пока разные решения, и все они выглядят грязными. Есть идеи?

Редактировать

Вот небольшой проект, который демонстрирует это:

Это ProductController:

public class ProductController : Controller {

    [HttpPost]
    public ActionResult Search(SearchModel searchModel) {

        if (ModelState.IsValid) { 
            //Do some stuff...

            return RedirectToAction("Index", "SearchResult");
        }
        return View(searchModel);
    }
}

Это SearchModel:

public class SearchModel {

    [Required]
    public string ProductCategory { get; set; }

    [Required]
    public string ProductName { get; set; }
}

Это * _SearchPartial *:

@model MvcApplication20.SearchModel

@using (Html.BeginForm("search", "product"))
{
    @Html.EditorForModel()

    <input type="submit" value="Search" />
}

И, наконец, это Home вид действия контроллера Index, который отображает * _SearchPartial *:

@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>

@Html.Partial("_SearchPartialView")

Здесь, когда я отправляю форму и если состояние модели не удается, как мне поступить в действии Product controller Search?

Ответы [ 2 ]

2 голосов
/ 13 февраля 2012

Здесь, когда я отправляю форму и если состояние модели не удается, как мне поступить при выполнении действия Поиск контроллера продукта?

Обычно в этом случае вы должны визуализировать _SearchPartialView но не как частичный, а как полный вид с макетом, чтобы пользователь мог исправить свои ошибки.В этом случае вам не нужно оставаться дома / в индексе:

[HttpPost]
public ActionResult Search(SearchModel searchModel) {

    if (ModelState.IsValid) { 
        //Do some stuff...

        return RedirectToAction("Index", "SearchResult");
    }
    // since we are returning a view instead of a partial view,
    // the _SearchPartialView template should be displayed with the layout
    return View("_SearchPartialView", searchModel);
}

И если вы хотите остаться на той же странице в случае ошибки, вы можете использовать вызов AJAX для выполнения поиска.Таким образом, вы должны AJAXify эту форму поиска, а затем в тесте обратного вызова успеха результат действия поиска и на его основе решить, обновлять ли частичное, чтобы показать ошибку или перенаправить на действие результатов, используя window.location.href:

что-то вроде:

$(document).on('submit', '#searchForm', function() {
    $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(), 
        success: function(result) {
            if (result.redirectTo) {
                // no validation errors we can redirect now:
                window.location.href = result.redirectTo;
            } else {
                // there were validation errors, refresh the partial to show them
                $('#searchContainer').html(result);

                // if you want to enable client side validation
                // with jquery unobtrusive validate for this search form
                // don't forget to call the .parse method here 
                // since we are updating the DOM dynamically and we
                // need to reattach client side validators to the new elements:
                // $.validator.unobtrusive.parse(result);
            }
        }
    });
    return false;
});

Это, очевидно, предполагает, что вы теперь обернули частичный вызов в div с id="searchContainer" и что вы указали id="searchForm" при создании формы поиска:

<div id="searchContainer">
    @Html.Partial("_SearchPartialView")
</div>

и теперь поисковое действие:

[HttpPost]
public ActionResult Search(SearchModel searchModel) {

    if (ModelState.IsValid) { 
        //Do some stuff...

        return Json(new { redirectTo = Url.Action("Index", "SearchResult") });
    }
    return PartialView("_SearchPartialView", searchModel);
}
1 голос
/ 13 февраля 2012

Насколько я знаю, ModelState теряется при выполнении RedirectToAction, решением было бы сохранить состояние модели в TempData, один из примеров этого, который я использую, таков:

http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg

Это также обсуждается в различных сообщениях, например Передача данных MVC между представлениями

...