似乎有多种方法可以将模型数据从asp.net mvc中的控制器传递给视图。我不清楚在mvc v1和v2版本中是否有推荐的方法,或者像生活中的大多数事情一样,这取决于。我见过几种方法:
选项1 - 在视图中使用强制类型的索引方式填充控制器的ViewData dixtionary,或者通过创建强类型自定义模型类并通过ViewData传递它来以强类型方式填充。
选项2 - 使用ViewData.Model,我不确定我是否理解。
选项3 - 使用ViewPage.Model,在这种情况下,我不确定如何从控制器传递模型数据。
我已经看过一些帖子poo-pooing选项1和2,但我不明白为什么。在大多数情况下,这些帖子似乎强烈推荐3。
你怎么做到这一点?有标准的方法吗?
答案 0 :(得分:2)
每个视图'都应该'具有特定的模型。这有时候是更多的工作,所以人们使用像ViewData
这样的捷径,但是在我看来,它只是不那么干净和类型安全,所以我更喜欢在视图的模型中包含所有内容。
然后,您可以强行输入所有观看次数。这是一种非常干净的方法。然后在您的控制器中,您只需调用视图:
YourViewModel model = new YourViewModel()
{
// initialize the data here
};
View(model);
然后在您的观看中,您可以通过ViewPage
Model
访问所有数据,它也是安全的,并且也可以从控制器强制执行。
来自评论的编辑:
如果您不想要,则根本不需要使用ViewData
。您可以将视图中所需的所有数据封装在模型中。就像你用ProductsListViewData
引用的例子一样。它只是一个模型,其中包含将要存储在ViewData
中的所有项目。两种方式都可以工作,但是当你将它封装在一个类中时(所有内容都在模型中的首选方法),所有的位和部分都是强类型的。
ViewData
是一个通用容器,所以即使您可以将任何您想要的东西放入其中,它也不是类型安全的,因此不是“干净”。它归结为偏好和可维护性。只有选项1和3.您的选项2被误解,实际上只是选项3。 ViewData.Model
只有ViewPage.Model
。
答案 1 :(得分:1)
您可能希望在视图变得更复杂时考虑一种方法,即保留使用模型作为输入字段,并使用ViewData支持View需要呈现的任何其他内容。
至少有几个论据支持这一点:
您有一个主页面需要一些数据(例如标题中的StackOverflow用户信息)。应用站点范围的ActionFilter可以在每次操作后轻松地在ViewData中填充此信息。将它放入模型中需要网站中的每个其他模型都从基础模型继承(这最初可能看起来不是很糟糕,但它可能很快变得复杂)。
当您验证已发布的表单时,如果存在验证错误,您可能希望将模型(使用无效字段)重新绑定到视图并显示验证消息。这很好,因为输入字段中的数据被回发并将绑定到模型,但是您的视图需要重新填充的任何其他数据呢? (例如,下拉列表值,信息消息等)这些将不会被回发,并且它可能变得混乱,将这些重新填充到模型“围绕”回发的输入值。通过使用.view数据填充ViewData的方法通常更简单。
根据我的经验,我发现这种方法效果很好。
而且,在MVC3中,dynamic ViewModels意味着不再有字符串索引!
答案 2 :(得分:0)
答案 3 :(得分:0)
(我知道以下答案非常有争议,但这只是我喜欢的方式)
我会说使用ViewData来处理简单的数据任务,并将模型用于View的主要目的。在这里查看Rob Conerys ViewData帮助程序类,为它们提供更强烈的类型感觉:
http://blog.wekeroad.com/2010/01/20/my-favorite-helpers-for-aspnet-mvc
绝对使用模型一切都会使你的项目膨胀,数百种模型只是为了实现最小的东西。我的意思是,如果您有一个用户设置页面,您通常会将用户模型传递到视图中,但是如果您决定显示一些相关数据,例如客户与此用户相关。你坚持使用以下解决方案
OR
你可以做ViewData [“Customers”] = myRepo.GetCustomersRelatedTo(用户); //或类似的东西。
在您的视图中和(如果使用Robs助手):
<%= Html.RenderPartial(“CustomerList”,Html.ViewData(“Customers”))%> 添加一个名为CustomerList的PartialView,它采用IEnumerable
在我的拙见中,这是一个更清晰的解决方案,当然 - 你最终会在这里和那里找到一个神奇的字符串,但我会坚持这种方法,直到有人向我展示一个没有单一魔法字符串的项目。
使用我们在框架中使用的工具来完成工作。保持简单......;)