来自不同控制器操作和 ModelState 的 HTTP Post 请求
我对 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" />
}
最后这是呈现 *_SearchPartial* 的 Home
控制器 Index
操作视图:
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
@Html.Partial("_SearchPartialView")
在这里,当我提交表单时,如果模型状态失败,我应该如何继续 <代码>产品控制器搜索
操作?
I have a weird need in an ASP.NET MVC 3 application which blocks my current progress. Here is the case:
I have a little search engine for the products and I render this search engine on multiple pages. This SE makes a HTTP POST request to product
controller's search
action. It fine till here.
Let's assume that I am on home
controller's index
action (/home/index). I make a search and check if ModelState.IsValid
. As a result, it is not valid. So, I should return this back with the entered model (so that user won't lose the values) and model state errors. But when I do that I ended up with different URL (/product/search) as expected.
If I do a redirect, I lose the ModelState
and cannot display error messages.
I have different solutions so far and they all look dirty. Any idea?
Edit
Here is a little project which demonstrates this:
This is the ProductController
:
public class ProductController : Controller {
[HttpPost]
public ActionResult Search(SearchModel searchModel) {
if (ModelState.IsValid) {
//Do some stuff...
return RedirectToAction("Index", "SearchResult");
}
return View(searchModel);
}
}
This is the SearchModel
:
public class SearchModel {
[Required]
public string ProductCategory { get; set; }
[Required]
public string ProductName { get; set; }
}
This is the *_SearchPartial*:
@model MvcApplication20.SearchModel
@using (Html.BeginForm("search", "product"))
{
@Html.EditorForModel()
<input type="submit" value="Search" />
}
And finally this is the Home
controller Index
action view which renders the *_SearchPartial*:
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
@Html.Partial("_SearchPartialView")
Here, when I submit the form and if the model state fails, how should I proceed at the Product
controller Search
action?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我所知,在执行 RedirectToAction 时 ModelState 会丢失,解决方案是将 modelstate 保存在 TempData 中,我正在使用的一个示例是:
http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg
这也在各种例如帖子 MVC 在视图之间传输数据
As far as I know the ModelState is lost when doing a RedirectToAction, the solution would be to save the modelstate in the TempData one example of this, that I'm using is this:
http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg
This is also discussed in various posts for instance MVC Transfer Data Between Views
通常在这种情况下,您应该渲染
_SearchPartialView
但不是部分视图,而是带有布局的完整视图,以便用户可以修复错误。在这种情况下,无需停留在主页/索引:如果您想在发生错误时停留在同一页面上,您可以使用 AJAX 调用来执行搜索。因此,您可以 AJAX 化此搜索表单,然后在成功回调中测试搜索操作的结果,并根据结果决定是否刷新部分内容以显示错误或使用 window.location 重定向到结果操作。 href:
大致如下:
这显然假设您现在已使用
id="searchContainer"
将部分调用包装在 div 中,并且您提供了id=" searchForm”
生成搜索表单时:现在搜索动作:
Normally in this case you should render the
_SearchPartialView
but not as a partial but as a full view with layout so that the user can fix his errors. No need to stay at Home/Index in this case:And if you wanted to stay on the same page upon error you could use an AJAX call to perform the search. So you would AJAXify this search form and then in the success callback test the result of the Search action and based on it decide whether to refresh the partial in order to show the error or redirect to the results action using
window.location.href
:something along the lines of:
This obviously assumes that you have now wrapped the partial call in a div with
id="searchContainer"
and that you provided anid="searchForm"
when generating the search form:and now the search action: