MVC 在视图之间传输数据

Posted

技术标签:

【中文标题】MVC 在视图之间传输数据【英文标题】:MVC Transfer Data Between Views 【发布时间】:2010-06-23 15:27:50 【问题描述】:

我刚开始学习 MVC,并试图了解它是如何工作的。

我不想将用户发送到所有编辑、插入和列表操作的不同视图。

在我的示例应用程序中,一个视图包含一个项目列表,在列表下方有一个表单(用于插入新项目),其操作为“Controller/Create”,但没有创建视图。

当用户插入一个新项目时,它会使用 httpverb post 发布到 Create 操作,并创建该项目并使用 RedirectToAction 方法返回到 List 操作。

但我无法以这种方式向用户显示任何消息(错误、信息等),因为我无法在创建操作和列表操作之间传递数据。我该怎么做?

【问题讨论】:

【参考方案1】:

您需要使用 Post Redirect Get PRG 模式。

请阅读 Kazi Manzur Ra​​shid 的这篇博文中的使用 PRG 模式进行数据修改部分。http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx

这种方法使用TempData 在重定向之间维护ModelState 数据。

[HttpPost, ValidateAntiForgeryToken, ExportModelStateToTempData]
public ActionResult Create(FormCollection form)

    Product p = new Product();

    if (TryUpdateModel<IProductModel>(p))
    
        productRepository.CreateProduct( p );
    
    else
    
        // add additional validation messages as needed
        ModelState.AddModelError("_generic", "Error Msg");
    

    return RedirectToAction("Index");

这是您的Index 操作方法。

[ImportModelStateFromTempData]
public ActionResult Index()

    IList<Product> products = productRepository.GetAll();
    return View("Index", products);

这是您的Index 视图。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IList<Product>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Products</h2>

    <% foreach (var p in Model)  %>
        <div><%= html.Encode( p.ProductName ) %></div>
    <%  %>

    <%= Html.ValidationSummary("Please correct the errors", new  id = "valSumCreateForm" ) %>
    <% using (Html.BeginForm("Create", "Product"))  %>
        Product Name: <%= Html.TextBox("ProductName") %>
        <%= Html.AntiForgeryToken() %>
        <% ViewContext.FormContext.ValidationSummaryId = "valSumCreateForm"; %>
    <%  %>
</asp:Content>
    ImportModelStateFromTempDataExportModelStateToTempData 属性有助于转移模型 重定向之间的状态错误。这个 &lt;% ViewContext.FormContext.ValidationSummaryId = "valSumCreateForm"; %&gt; 将 MVC 表单与其对应的验证摘要相关联。

你也可以在这里查看我的另一个答案。 ViewModel with SelectList binding in ASP.NET MVC2

如果您有任何问题,请告诉我。 -苏

【讨论】:

【参考方案2】:

大多数 MVC 框架都能够在下一个请求时临时存储少量数据,仅用于此目的。在 ASP.NET MVC 中称为 TempData,在 Rails 中称为 :flash 等。

【讨论】:

Tempdata 不是最佳选择,应避免使用。参考下面为什么tempdata不好:jonkruger.com/blog/2009/04/06/… 在您提到的帖子中描述的示例中, TempData 仍在使用中,它只是被包装了,因此没有被明确引用。即使在这种方法中,TempData 也是传递此类数据的正确机制;不同之处在于您使用 TempData 的方式。【参考方案3】:

This article 解释如何使用TempData

最烦人的事情之一 处理Web编程中的错误 在表格上。更具体地说,你想要 显示错误消息,但您 想保留之前输入的 数据。我们都经历过 在有 35 的表格上犯错 字段,只提供一个 一堆错误信息和一个新的, 空白表格。 MVC 框架提供 TempData 作为存储先前输入信息的位置,以便可以重新填充表单。 这是 ViewState 实际制作的东西 在 Web 表单中非常容易,因为保存 控件的内容很漂亮 很自动。 ... TempData 是一个字典, 很像无类型的 ViewData。 但是,仅 TempData 的内容 为一个请求而活,然后 它们已被删除。

【讨论】:

以上是关于MVC 在视图之间传输数据的主要内容,如果未能解决你的问题,请参考以下文章

请为 MVC3 命名一些教程,它显示了从控制器到视图的数据传输

如何在布局中的视图之间传输数据

asp.net mvc 在视图和控制器之间传递参数

如何在MVC视图之间显示“正在加载”

如何使用 Swift 委托模式在视图之间传输数据

如何在父视图控制器和子视图控制器之间传输数据