我在ASP.NET MVC 3应用程序中有一个奇怪的需求阻止了我当前的进展。情况就是这样:
我有一些产品的搜索引擎,我在多个页面上渲染这个搜索引擎。此SE向product
控制器的search
操作发出HTTP POST请求。它很好,直到这里。
我们假设我在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
控制器Search
操作?
答案 0 :(得分:2)
在这里,当我提交表单时,如果模型状态失败,应该怎么做 我继续进行产品控制器搜索操作?
通常情况下,在这种情况下,您应该呈现_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
重定向到结果操作:< / p>
类似于:
$(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;
});
这显然假设您现在已将部分调用包含在id="searchContainer"
的div中,并且在生成搜索表单时提供了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 :(得分:1)
据我所知,当执行RedirectToAction时ModelState丢失了,解决方案是将模型状态保存在TempData的一个例子中,我正在使用的是:
http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg
这也在各种帖子中进行了讨论,例如MVC Transfer Data Between Views