MVC 3形成post和持久模型数据

我想我错过了关于MVC表单如何工作的一些基础知识。 我的主页上有一个搜索表单,有五六个不同的字段供用户搜索。 所以我对我的结果动作进行了这个post就好了。 Result操作如下所示:

[HttpPost] public ActionResult Results(SearchModel model) { ResultsModel results = new ResultsModel(); results.ResultList = SearchManager.Search(model).ToList(); return View("Results", results); } 

我为这篇文章简化了上面的方法,但想法是一样的。 所以一切正常。 我的结果页面显示结果列表,我的用户位于以下URL:

http://www.site.com/results

所以…现在我想做一些相当普遍的事情。 我在结果页面上有两个下拉列表。 “排序依据”和“每页结果数”。 我该怎么做并将全套模型数据发送回控制器,以便我可以查询新参数? 实际上,SearchModel类有大约60个不同的字段。 所有这些数据都可能包含在模型中。 你如何坚持到“回帖”的页面?

同样的问题让我对如何进行分页感到有点困惑。 我的分页链接将转到以下URL:

http://www.site.com/results/2

但是这假设我们正在响应GET请求(我不想在查询字符串中使用60个数据字段)并且模型数据在GET请求之间传递,我知道情况并非如此。

正如我所说的,我认为我缺少一些关于使用MVC 3,模型和表单post的基础知识。

谁能帮助我指出正确的方向? 我很乐意根据需要编辑/更新这篇文章以澄清事情。

编辑 :我也想指出,我想避免将视图模型存储在Session变量中。 这个站点最终将最终在Web场中进行负载平衡,并且我真的试图尽可能避免使用Session。 但是,如果它是唯一的选择,我将配置另一个会话状态提供程序,但我不想这样做。

您可以将当前的SearchModel参数添加到表单的路由值。 几个版本的BeginForm允许您传入一个对象/ RouteValuesDictionary。

 @Html.BeginForm("Action", "Controller", new { SearchModel = Model }, FormMethod.Post) 

这应该传递您当前的SearchModel值,以便您可以重复使用它们来获取下一页。 您需要定义一个控制器操作,它将接受任何当前页面的表单值以及SearchModel。

我没有使用表单发布这个,但是从我所做的和文档的内容来看,这就是我要开始的地方。 当然,这也意味着页面上的每个页码“链接”都需要发帖。 如果用户希望能够使用浏览器中的“后退”按钮,那对用户来说真的很不方便。

在此上下文中,您可以尝试定义允许页码作为URL的一部分显示的路由 – “Action / Controller / {page}”。 但是,鉴于表单正在发布post,我不确定它是如何工作的。

对评论的回应:

是的,您可以使用Route Values将SearchModel添加到每个页面链接,但正如我在上面的评论中所说,由于链接将执行“获取”,您的用户将看到SearchModel被序列化为链接的一部分。

无论哪种方式,使用路由值是您在不使用隐藏字段,会话或TempData的情况下获取原始SearchModel的答案。

您的SearchModel类需要包含搜索条件和结果。 像下面的东西。 如果您对结果使用PagedList,则它将包含当前页面,总页数,总项目等。您可以通过仅编写包含值的搜索条件来限制页面中的信息量。

 public class SearchModel { public string Product { get; set; } public string Sku { get; set; } public string Size { get; set; } public string Manufacturer { get; set; } // etc... public PagedList ResultsList { get; set; } } [HttpPost] public ActionResult Results(SearchModel model) { model.ResultList = SearchManager.Search(model).ToList(); return View(model); } 

我在这里提出的一个选项是实现一个分布式缓存系统,它支持充当自定义会话提供程序(即Memcached或Windows Server AppFabric),从而允许我在负载平衡环境中使用TempData(和Session)像这样:

 [HttpPost] public ActionResult Results(SearchModel model) { ResultsModel results = new ResultsModel(); results.ResultList = SearchManager.Search(model).ToList(); TempData["SearchModel"] = model; return View("Results", results); } [HttpGet] public ActionResult Results(int? page) { SearchModel model = (SearchModel)TempData["SearchModel"]; ResultsModel results = new ResultsModel(); results.ResultList = SearchManager.Search(model).ToList(); TempData["SearchModel"] = model; return View("Results", results); } 

有关这种方法的任何想法? 看起来很多只需要在请求之间传递搜索参数。 或者也许我只是被WebForms在幕后发生的事情所破坏。 🙂

这似乎是Webforms被宠坏的人的另一个有趣的选择;) 使用Serialize HTMLHelper在ASP.NET MVC中保持模型状态某种ViewState化身。 它是MVC Futures的一部分。 不确定Futures项目有多长,以及为什么它无法进入主lib。