MVC 3表单post和持久化模型数据

本文关键字:持久化 模型 数据 post 表单 MVC | 更新日期: 2023-09-27 17:54:19

我想我错过了一些关于MVC表单如何工作的基础知识。我在我的主页上有一个搜索表单,其中有五到六个不同的字段可供用户搜索。所以我有这个张贴到我的结果行动很好。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

所以…现在我想做一些很普通的事情。我在结果页面上有两个下拉列表。"排序方式"answers"每页结果数"。我如何做到这一点并将全套模型数据发送回控制器,以便我可以使用新参数进行查询?实际上,SearchModel类有大约60个不同的字段。所有这些数据都可能包含在模型中。如何将其持久化到"post back"页面?

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

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

但是,假设我们正在响应一个GET请求(我不希望在querystring中有60个字段的数据),并且模型数据在GET请求之间传递,我知道情况并非如此。

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

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

EDIT:我还想指出,我想避免将视图模型存储在会话变量中。这个网站最终将在一个web farm中实现负载平衡,如果可能的话,我真的在尽量避免使用Session。但是,如果这是唯一的选择,我将配置另一个会话状态提供程序,但我不希望这样做。

MVC 3表单post和持久化模型数据

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

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

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

我还没有在表单帖子中这样做过,但从我所做的和文档所说的来看,这是我要开始的地方。当然,这也意味着你在页面上的每个页码"链接"都需要做帖子。如果用户想要在浏览器中使用后退按钮,这对他们来说是非常不方便的。

在这种情况下,你可以尝试定义一个路由,允许页码作为URL的一部分出现——"Action/Controller/{page}"。然而,我不确定这将如何工作给定的形式是做一个帖子。

对评论的回应:

是的,你可以使用路由值将SearchModel添加到每个页面链接中,但正如我在上面的评论中所说,由于链接将执行"get"操作,你的用户将看到SearchModel序列化为链接的一部分。

无论哪种方式,使用路由值都是您在不使用隐藏字段,Session或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被宠坏的家伙的另一个有趣的选择;在ASP中持久化模型状态。. NET MVC使用Serialize HTMLHelper某种ViewState的化身。它是MVC Futures的一部分。不确定它在Futures项目中有多长时间,以及为什么它不能进入main lib。