在 MVC3 中,我应该有单独的"edit"模型还是 "display"模型?



与MVC3,我应该设计我的视图模型,这样有一个是绑定到视图(DisplayModel),一个是发布回控制器(EditModel)?

澄清一下,我不是在问数据模型vs.视图模型——我知道将我的视图/控制器绑定到数据/域模型是不好的。

我也不要求在两个独立的视图之间共享一个模型,一个视图用于显示数据,另一个视图用于编辑数据。

相反,我问的是一个用于编辑数据的视图,以及绑定到视图的模型与绑定到控制器动作的模型。

换句话说,如果这是我的观点:

@model MyApp.Models.CustomerModel

我的控制器动作应该看起来像:

public ActionResult Index(CustomerModel model)

或:

public ActionResult Index(CustomerEditModel model)

在某一时刻,我们正在做后者(单独)。但最近,我们开始做前者(共享)。

这个变化的原因是:

  1. 对于MVC3不显眼的验证,如果我在模型上使用DataAnnotations进行验证,那么如果两个模型是分开的(在显示模型上映射客户端验证,在编辑模型上映射服务器端验证),则这两个模型都需要。

  2. 随着应用程序的成熟,我们意识到除了视图模型中的选择列表外,显示模型和编辑模型有95%是相同的。我们现在已经把它们移动到一个共享类中,并通过视图传递它们。

但是我已经看到了一些其他的讨论,指出共享模型的视图/控制器是一个坏主意,它违反了分离的关注。

有人能帮我理解这两种方法的权衡吗?

我已经看到了非常好的支持和反对的论据,这只是取决于什么最适合您的应用程序。没有放之四海而皆准的方法!

如果你还没有读过Jimmy Bogard写了一篇关于他的团队如何做MVC的非常好的文章,其中涵盖了这个主题。

我同意rich。凯利的回答是没有正确的方法。

对于使用一个模型,我有几个问题。

当视图需要显示一个可选择的对象列表时,总是使用一个没有不必要属性的模型将是非常好的。模型需要对象列表和一个属性来接受用户选择的post值。这些不需要的属性增加了少量的代码混乱和开销。(解决这个问题的一种方法是让模型只包含选定的ID,并使用HTML助手来构建列表。)

另一个问题与安全性有关。一个常见的场景是在应该被认为是只读的表单中显示信息。在ViewModel和EditModel的情况下,EditModel将只包含预期要被post的属性,而ViewModel将包含所有的属性。例如,如果一个表单显示一个用户的工资,用户将能够POST一个'salary',并通过MVC自动将其绑定到ViewModel的salary属性。此时,必须对做一些操作,以确保它不会最终进入数据库。它可以是if/else逻辑、Bind属性、Automapper逻辑或其他东西,但关键是这是一个可能被忽略的步骤。在考虑应用程序的生命周期时,我喜欢EditModel随时间变化的显式性。

这些问题并不意味着两个模型是好的,一个模型是坏的,但是在选择设计时应该考虑这些问题。

如果显示和编辑视图模型的属性是相同的,我认为没有理由有单独的类。

我想你会发现不管你走哪条路,它都是成功或失败的,但如果你能选择最容易维护的道路,那么你应该这样做。根据我的经验,拥有一个模型显然更容易维护,但是似乎总是有一些业务决策迫使我拆分模型。如果你在95%的范围内,那么我认为你的身材真的很好。从与模型相关的可维护性角度来看,您的应用程序将易于维护。当一个变化出现时,你有一个地方可以做出改变,在大多数情况下。我经常遇到的问题是跨多个模型扩展业务变更。复制/粘贴问题,或者只是忘记了一些属性的地方,似乎总是伤害我,因为多模型的问题。

我们意识到我们的显示和编辑模型是95%相同的除了视图模型中的选择列表。我们现在把它们移到一个共享类中,并通过视图传递它们。

它们在数据和操作上是95%相同还是仅仅在数据上相同?记住,类封装了数据和行为。

如果它们在属性上有95%相似,但操作完全不同,那么将它们分成两个类可能会受益。或者你可能没有:)

正如其他人指出的那样,没有一个放之四海而皆准的答案,在你的情况下,似乎一个类是OK的…但如果你开始注意到他们每个人的行为都是无关的,不要害怕重新考虑你的方法。

两个方向都没有一个视图模型。将它们混在一起不仅难以遵循,而且很容易将无效值注入页面,然后自动绑定。例如,我可以覆盖您的customerid(或创建一个)。

从基视图模型继承,如果你必须或不依赖于数据注释,并使用fluent api在你的模型保存。

一个很好的链接(有些不相关,但自动地图很好)

编辑(抱歉其他人之前在下面发布了这个,我才意识到)http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

也ASP.net MVC -每个视图或每个动作一个视图模型?

你(IMHO)应该通常绑定到你的方法特定的VieWModel,而不是一个共享的视图模型。您可能会陷入丢失属性等陷阱,但它也可能对您来说工作得很好。

使用自动映射器在两者之间切换。Jimmy在返回到视图时也有一个很好的AutoMap属性。回到另一种方式,我一般不会使用CustomerModel,因为那里可能需要的字段不是来自我的创建视图。例如,客户id可能是必填字段,但对于"创建"操作,它不会出现。但是,如果你发现在大多数情况下,这实际上是为你工作,那么没有理由不使用它。

相关内容

  • 没有找到相关文章

最新更新