asp.net mvc强类型助手 - 你的渲染绑定对象应该与你的发布对象相同吗?

时间:2010-01-16 22:14:48

标签: asp.net-mvc data-binding

我看到asp.net mvc 2有强烈的输入帮助,并且最初看它的工作方式我认为也许我在asp.net mvc 1中做错了数据绑定以呈现视图并回发到控制器。

我经常有不同的对象来渲染视图并回发到控制器。这是错的?这似乎很自然,因为在渲染视图时,您经常会有一个包含下拉列表等的视图模型,但对于您的发布,您只需要回发所需的属性。

例如,在进行渲染的过程中,我的viewmodel可能看起来像这样

 public class PersonViewModel
 {
      public int Age;
      public string FIrst;
      public JobCategory[] JobCategories;
      public Sport[] Sports;
      public int NumberOfChildren;

 }

在这种情况下, jobCategories 体育将用于填充下拉框。 NumberOfchildren 将只是html放入,我不希望它可编辑。当我想发布我只想传回一个苗条的对象只有发布的属性,所以我有另一个对象

  public class PersonUpdater
 {
      public int Age;
      public string FIrst;
      public int JobCategoryId;
 }

这些是我需要传回的唯一属性,因此我的控制器将如下所示:

 public ActionResult Update(PersonUpdater personUpdater)
 {
      _repository.UpdateModel(personUpdater). 
 }

所以,鉴于上述情况,假设强类型辅助方法(如下所示)似乎对进入方式有用,但如果您引用不同的属性,则可能会导致回发到服务器的问题。

http://weblogs.asp.net/scottgu/archive/2010/01/10/asp-net-mvc-2-strongly-typed-html-helpers.aspx

有什么想法吗?

7 个答案:

答案 0 :(得分:7)

真正的问题是 - 当前接受的方法忽略SRP视图模型 - 编辑形式同时充当输入和输出。

人们尚未接受将view model分为input view model,我称之为output view modelview model(对于许多人来说 - 甚至创建view model图层太多了)。因此 - Mvc2目前缺乏对此的支持(你不应该同时具有非输入和输出的强类型视图)主要是因为模糊和缺乏广泛接受的方法。

但是我确实认为,在更深入地将{{1}}分成2个时,有一个好处(好吧......这实际上是一种权衡)。如果这个想法能够发展并最终被广泛接受,我也不会感到惊讶。

实际上 - 当前的方法甚至有一个名字 - Thunderdome principle。如果杰里米·D·米勒(Jeremy D. Miller)这样的人说这是正确的,那么社区就不会费心去寻找其他任何东西。


从实际角度来看 - 您可以通过提供正确的元数据来缓解一些问题(您可能需要查看fluent model metadata provider)。

答案 1 :(得分:0)

您可以在强类型帮助器中指定要引用的属性,查找包含3个参数的重载。

你的方法没问题。 强大的类型视图可以帮助您更好地发展,所以没有typpo会妨碍你。

答案 2 :(得分:0)

我建议只使用一个GET和POST对象来保持简单。代码可维护性在这里比为更新操作保存几个字节更重要/更有价值。

Arnis就SRP和其他设计模式提出了很好的论据,但是Petterns应该被改编。如果我是你,我会使用mvc框架为你创建的帮助:使用键入的助手;使用类型化的模型/ viewmodel对象进行GET / POST,如果需要更复杂的绑定,可以创建自定义绑定器。

保持代码清淡,你的应用程序将保持真棒。

答案 3 :(得分:0)

我使用模型进行输入(由表单显示)和单独的输出模型(由表单发布)。验证放在输出模型上。我这样做的具体原因是下拉列表。您需要向用户显示可能值的列表,这些值在输入模型中。在表单的输出或发布中,我不想要可能的值列表,我想知道用户选择的值(如果有的话)。

答案 4 :(得分:0)

除了两个模型相同之外,我还为输入[GET]和输出[POST]使用单独的视图模型。恕我直言,这种方法更清晰,更易于维护,并且更清楚地表达了给定控制器操作将更新哪些数据。

就LOC而言,这是一个成本,但额外的代码通常不是逻辑。在大多数情况下,我不认为在两个对象上复制某些自动属性违反了DRY原则,我认为跟踪SRP的成本是合理的。

正如您所指出的,其他成本是内置的强类型帮助程序不能很好地工作。您是否考虑过编写支持您的模式的助手?例如,您可能会重载其中一个现有助手,以便您可以同时指定(例如输入模型的属性)和目标(例如,发布到输出模型的表单字段。)

答案 5 :(得分:0)

只要看看你的具体情况,我就会发现以下几点。

1)两个模型确实非常相似 2)如果添加“MiddleName”,则必须在两个地方添加 3)当你说“我只想传回一个苗条的对象”时 - 实际的POST将包含相同数量的数据,无论你是绑定到原始模型还是新模型(它将包含一个键,值对每个表格中的用户输入) 4)您不能选择在“保存好的”或“无效的”页面上显示数据,因为它不是模型的一部分

由于这些原因,我建议使用相同的模型进行操作的GET和POST。

答案 6 :(得分:-1)

大多数情况下,自动绑定的东西不适合我需要的东西所以我只需要发布到formCollection参数并进行手动操作。如果你可以使用模型绑定魔法的任何部分,那么对你来说就更好了。

绑定较少并不意味着将较少的数据发回服务器。表单中的所有输入元素都将被传输,您不会将它们视为离散的,强类型的“自动”参数。如果你真的想减少帖子数据,你必须限制你发布的特定表格中的输入元素。毕竟MVC仍然是HTTP ......