为每个Model CRUD操作分离ASP.NET MVC View对象?

时间:2011-10-12 19:41:48

标签: asp.net asp.net-mvc

我一直在阅读的大多数MVC教程似乎为每个模型创建了4个View对象。例如,如果我的模型是“Foo”,则似乎有4个.cshtml文件:Foo / Create,Foo / Delete,Foo / Details和Foo / Edit。使用VisualStudio“scaffolding”帮助程序也可以做到这一点。

这真的被认为是MVC的最佳实践吗?让4个类彼此相同的80-90%是错误的。当我向Foo添加一个新字段时,我需要编辑所有4个.cshtml文件。这种双重维护(四维维护?)只是让我的OO皮肤爬行。

请告诉我:是否有预期/接受的最佳做法,以不同的方式处理这个问题?或者,如果这真的被接受为最佳实践,请告诉我为什么四维不应该让我感到不安。

我是一位相当熟练的ASP.NET / c#/ OO设计老手,但对于MVC来说却是一个新手;如果这是一个菜鸟问题,请道歉。在此先感谢您的帮助!

编辑:感谢所有回复!我标记了最彻底的一个作为答案,但赞成所有有用的。

5 个答案:

答案 0 :(得分:5)

您可能需要两到四种不同的观点:

  • 列表(用于查看许多内容)
  • 查看(查看单个内容。可能没有必要,如果可以使用“编辑为视图”,或者“列表有空间显示所有属性”)
  • 创建
  • 编辑(如果巧妙编码,可以与创建相同)

因此,如果您的模型没有太多属性可以在表格中显示它们,并且如果您没有静态的,不可编辑的视图来进行检查,那么您可以很好地完成列出并编辑,并废弃其他两个。

但是,如果您更新模型,这并不能解决您的双重(或三重)维护问题。还有其他的魔力;)

在ASP.NET MVC 3中,HtmlHelper上有一些扩展程序可以让您Html.DisplayForModel()Html.EditorForModel()。它们使用预定义模板将自己嵌套到对象中,并为所有公共属性绘制显示/编辑字段。如果您传递DisplayForModel IEnumerable<Foo>,它将创建一个包含列标题的表,该列标题是Foo的属性名称(如果您提供了DisplayName属性信息,则使用此属性信息)其中每行代表一个Foo实例。如果您EditorForModel Foo,则会为<label>上的每个公共媒体资源创建<input>Foo

如果您对默认设置不满意,可以替换这些强大的扩展方法使用的所有模板。这可以在Foo级别上完成,在这种情况下,您将返回双重维护方案,或者在较低级别(例如stringDateTime)影响使用模板生成的所有编辑器/显示字段。

有关其工作原理的更多信息,请google "ASP.NET MVC 3 editor templates"阅读并阅读几个教程。他们会比我更好地解释细节。

答案 1 :(得分:1)

ASP.NET MVC为您创建的视图不一定需要是您在生产中使用的视图。我发现这些只是在开发快速原型或测试数据库CRUD操作时很方便。随意创建您想要处理操作的任何视图。

我通常只有1或2个视图来处理基本操作,而不使用生成的内置视图。例如,1个用于添加,编辑或详细信息的视图和1个用于显示对象列表的视图。

答案 2 :(得分:1)

这一切都取决于你的申请。

如果您有一个项目,则不需要列表视图。如果您无法编辑它,则不需要编辑视图。创建和编辑通常可以是相同的视图,除非您需要在一个视图中执行特殊操作,而不是另一个视图。

换句话说,根据需要使用尽可能多的视图。这里没有硬性规定。脚手架就在那里帮助你。使用脚手架可以很好地使用多种应用程序,并且不需要高级HTML或Javascript。

为什么要多个视图?好吧,我们来看看显示和编辑功能。您可以创建一个视图,在该视图中使用if语句来确定视图的编辑模式,但是这会使视图逻辑变得复杂,并且视图应该尽可能简单。

创建单独视图的原因是它比一个巨大的条件逻辑中的一个巨大视图更容易维护。

答案 3 :(得分:0)

我倾向于为对象的CRUD操作创建以下内容:

  • 索引
  • _form (部分)
  • 更新
  • 删除
  • 视图

由于新版和更新版之间共享相同的形式,因此两者之间的差别很小。这真的取决于你想要变化多少,老实说。

至于删除,这是可选的。我希望有一个视图,以防javascript被禁用。

编辑: 你提到了视图模型,上面的人发布了一个冗长,错综复杂(无攻击)的虚拟机代码示例。

就个人而言,我讨厌编写的基本镜像域对象的类,仅用于“移动”数据。我讨厌虚拟机。我讨厌DTO。我讨厌所有让我必须编写更多代码的东西。

我想我已经喝了其他框架(rails,sinatra,node.js)的coolaid到了我无法忍受将DRY扔到风中的想法。

我个人说跳过嗯。

Edit2 我忘了清单..

答案 4 :(得分:0)

执行[HttpGet]时,您可以使用完全相同的视图。鉴于您将正确的ViewModel传递给此视图,无论您是否正在加载创建,更新或删除操作,它都会使用适当的数据填充。

当您尝试将该数据发布到特定操作时,问题就会变得明显。 自然视图应该只有一个表单,用于发布数据。声明此表单时,您可以指定要用于Post的确切操作。

在该表单中有3个不同的提交按钮不会产生任何影响,因为所有这些按钮都会将相同的表单发布到同一个Action。

您可以对OnClick事件进行一些javascript调整,以便这些按钮可以更改发布数据的Action,但这绝对不是最佳做法。

Buttom line:为每个CRUD操作提供4个不同的视图是MVC的最佳实践。