MVC 3形成帖子和持久模型数据

时间:2011-05-01 15:39:46

标签: c# asp.net-mvc forms viewmodel

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

[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请求之间传递,我知道情况并非如此。< / p>

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

任何人都可以帮我指出正确的方向吗?我很乐意根据需要编辑/更新这篇文章以澄清事情。

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

4 个答案:

答案 0 :(得分:16)

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

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

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

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

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

对评论的回应:

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

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

答案 1 :(得分:8)

您的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);
}

答案 2 :(得分:2)

我在这里提出的一个选项是实现一个支持充当自定义会话提供程序(即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幕后的所有事情所破坏。 :)

答案 3 :(得分:0)

对于Webforms被宠坏的人来说,这似乎是另一个有趣的选择;)Persisting model state in ASP.NET MVC using Serialize HTMLHelper 某种ViewState化身。它是MVC Futures的一部分。不确定Futures项目有多长,以及为什么它无法进入主lib。