【问题标题】:Best Practices for MVC.. ViewModel Binding using Interfaces ExampleMVC 的最佳实践.. ViewModel 绑定使用接口示例
【发布时间】:2011-10-27 10:19:49
【问题描述】:

我是 ASP.NET MVC 3.0 的新手,正在尝试使用 MVC ViewModel 设计构建应用程序。

我想知道为 ViewModel 重新分级控制器的最佳做法是什么,并在下面有几个问题。这是我目前的理解(可能是错误的)..

  • 我们创建模型。
  • 通过创建一个新类并声明与基本模型类具有相同名称和类型的属性来创建 ViewModel(包括您以后要更新的基本模型的 ID 字段......并且这些类没有以任何方式链接)。
  • 为每个基本模型创建一个存储库(以查找和保存数据等)。
  • 为每个 ViewModel 创建一个 Controller 操作(访问基类的存储库以检索值并将这些值放入 ViewModel,然后将 ViewModel 传递给 ViewModel 视图)。
  • 从 ViewModel 创建视图(ViewModel 视图)
  • 在 ViewModel 控制器更新 (POST) 方法中接收更新的 ViewModel 对象并将其转换为基本模型对象(也许使用 Automapper?),然后使用它们的存储库将基本模型对象保存回来并像这样应用绑定? "TryUpdate(人)", "TryUpdate(地点);" (这看起来不对,目的是将值从 ViewModel 放回基类,应用绑定,使用存储库将基模型保存回来!.. 这似乎没有使用存储库.. 而不是 TryUpdate (person); 我希望看到类似这样的内容:person.Save(IPerson).. 其中“person 包含值”、“.Save 是存储库”和“IPerson 包含用于绑定的绑定属性”? ..不确定这是否正确..

到目前为止,我已经通过创建一个新类并使用相同名称添加来自不同基础模型的属性来创建 ViewModel。此时我有以下问题:

Q1:每个 ViewModel 是否都有自己的控制器并访问每个基本模型存储库类以获取其值?

Q2:考虑到您可能希望通过 ViewModels 控制器将更新发布回基本模型存储库(需要 ID值)?

Q3:你将如何使用接口绑定属性,以便使用存储库保存控制器中的模型。

我一直无法找到一个教程或资源来解释一步一步的例子,一个完整的答案是下面的例子:

  • 2x 简单模型,1x 简单 viewModel,1x 用于绑定的接口,1x 使用接口类进行更新绑定的简单控制器,1x 存储库..即

//模型1

public class Person
{
  int PersonID {get;set;}
  string FirstName {get;set;}
  string LastName {get;set;}
  DateTime DOB {get;set}
}

//模型2

public class Place
{
  int PlaceID {get;set;}
  string Description {get;set;}
  string AreaType {get;set;}
  string PostCode {get;set;}
}

//ViewModel(包含模型的属性)

publc class ViewModel
{
  //Person attributes
  int PersonID {get;set;}
  string FirstName {get;set;}
  string LastName {get;set;}

  //Place attributes
  int PlaceID {get;set;}
  string Description {get;set;}
  string AreaType {get;set;}

  //other attributes
  string someOtherAttributeForDisplay {get;set}
}

//Model1接口(用于绑定模型)

public interface IPerson
{
  string FirstName {get;set;}
}

//Model2接口(用于绑定模型)

public interface IPlace
{
  string Description {get;set;}
  string AreaType {get;set}
}

//ViewModelController?

{
  //What goes here?
}

//存储库?

{
  //what goes here?
}

【问题讨论】:

  • 嗨 Mitch,我一直在研究使用 NuGet 将 Unity 和 EntLib 添加到我的项目中,但我不太确定它们的用途......

标签: asp.net asp.net-mvc asp.net-mvc-3 entity-framework c#-4.0


【解决方案1】:

我认为你可能把一个非常简单的概念过于复杂了。

首先是一些一般规则:

  • 不要使用 TryUpdateModel。只是不要。
  • 出于同样的原因,请勿使用任何“自动”映射映射器将您的视图模型映射到您的实体。反过来自动映射(从实体到视图模型)很好。

您不需要使用接口。

视图模型应该是非常简单的类,只包含视图所需的信息。如果您的视图 POST 与其显示的信息不同,那么只需为 POST 创建不同的视图模型。

我们为视图模型使用 {Controller}{Action}Model 的命名约定。因此,对于“Post”控制器上名为“List”的操作,我们将有一个名为“PostListModel”的模型。

最后,在这里查看我的回复Real example of TryUpdateModel, ASP .NET MVC 3

【讨论】:

  • 谢谢您的回复。您知道您可以通过在模型后面包含一个接口来绑定 TryUpdate 方法上的值吗?即 TryUpdate(person) 我在这里找到了一些我一直在关注的信息,但在我的版本中略有更改,以允许属性显示在视图中并稍后在控制器中绑定(这就是概念):codetunnel.com/blog/post/79/aspnet-mvc-model-binding-security。 . 你认为这家伙是在做某事还是不在他的摇杆上? :)
  • 在我看来,以这种方式使用接口只是为了解决使用 TryUpdateModel 的缺点(限制更新的属性),这可以通过简单的左右映射来实现。
  • 优点是你可以使用自动映射器来映射属性,这样你就可以通过不必进行左右映射来减少代码,相反你可以只传递对象。如果 Fiddler更改属性然后没关系,因为绑定不允许将值保存在 TryUpdate(model) 中,就像左右映射的工作方式一样。我想知道,ViewModel 需要哪个控制器?.. 它是自己的还是会使用基类控制器? :S..
  • 我看不出您正在保存任何代码,因为您必须为每个视图模型编写一个界面。视图模型没有对控制器的任何引用。您的控制器中的每个操作方法都应该有一个视图模型(就像在我的示例中一样)。
  • 我明白你的意思!.. :) 大声笑.. 唯一的优点是它减少了控制器中的代码,但我必须考虑它是否值得:S.. 哪个控制器你会推荐我的 ViewModel 示例,它使用来自 Person 模型和 Place 模型和其他属性的值.. 即 PersonController 或 PlaceController 来放置 ActionMethod。
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多