Asp.net mvc 视图模型和请求-响应消息传递模式之间的MVC映射

Asp.net mvc 视图模型和请求-响应消息传递模式之间的MVC映射,asp.net-mvc,design-patterns,automapper,asp.net-mvc-viewmodel,Asp.net Mvc,Design Patterns,Automapper,Asp.net Mvc Viewmodel,我有下面的MVC设计模式问题,并且不知道该走哪条路 在UI层中,在控制器操作方法中使用视图模型。酷 服务层使用请求-响应消息模式,因此服务类方法有一个请求对象作为参数(in),该方法返回一个响应对象(out)。此方法使用域对象参数调用存储库方法。换句话说,要调用服务方法,您需要用数据填充请求对象,该方法在响应对象中返回结果,即请求-响应消息传递 要将视图模型中的数据传递给服务方法中的域对象,AFAIK有两个选项: 确保请求对象包含与视图模型属性相同的属性,然后可以(手动或自动)将值从视图模型映射

我有下面的MVC设计模式问题,并且不知道该走哪条路

在UI层中,在控制器操作方法中使用视图模型。酷

服务层使用请求-响应消息模式,因此服务类方法有一个请求对象作为参数(in),该方法返回一个响应对象(out)。此方法使用域对象参数调用存储库方法。换句话说,要调用服务方法,您需要用数据填充请求对象,该方法在响应对象中返回结果,即请求-响应消息传递

要将视图模型中的数据传递给服务方法中的域对象,AFAIK有两个选项:

  • 确保请求对象包含与视图模型属性相同的属性,然后可以(手动或自动)将值从视图模型映射到请求对象
  • 请求对象包含视图模型的一个属性,即视图模型的实例现在位于请求对象中(与上面的选项不同-只有一个属性)。现在,您可以简单地将视图模型分配给请求对象中的属性
  • 我发现这两种方法都有缺陷

    在选项1中,如果视图模型有许多属性,并且您正在使用映射器(例如AutoMapper),那么在控制器方法中,您需要将属性从视图模型自动映射到请求对象。然后在服务层,在服务方法中,您需要将请求对象中的属性自动映射到域对象。两级映射-非常错误

    在选项2中,请求对象包含一个包含视图模型的属性。然后,您可以轻松高效地将Request.vm(属性)自动映射到域对象,但由于某些原因,这看起来像是糟糕的设计!我很关心这个设计


    哪种方法最好?或者有没有其他更好的方法来映射VM和R-R模式?

    在您上面描述的场景中,我没有请求对象

    我只是从服务层->表示层使用域对象(POCO类/实体)

    在准备来自控制器的响应时,我使用AutoMapper将从服务层返回的域对象转换为ViewModel对象

    如您所见,使用上述方法,选项1不再是一个问题。域到虚拟机,反之亦然,配置一次就完成了

    当web请求传入时,它有一个ViewModel对象,该对象在传递到服务层之前转换回域模型

    我不确定你是否认为它是“另一个”或“更好”的模式。如果您觉得这个主意不错,我可以根据需要提供更多信息。

    请求/响应是一种消息模式,但您似乎没有使用消息。。相反,您使用的是对象。这才是你问题的真正症结所在。您使用的模式不正确,更重要的是,您似乎使用了错误的工作模式。为什么在这种情况下需要消息传递?对于一个简单的多层应用程序来说,这只是额外的开销

    如果您真的想使用消息传递,您可能应该将数据序列化为json或xml,将其传递给您的服务,然后将数据反序列化为您在该层中使用的任何对象。这样,您就不需要对另一层的数据类型有任何依赖关系,因为(反)序列化过程不一定需要这种依赖关系


    就我个人而言,我会避免整个消息传递方面,并在视图模型和域对象之间建立映射层,然后使用域对象调用服务层

    这就是为什么我更喜欢实体框架,因为它允许我创建模型。我对所有内容都使用强类型,因此没有自动映射的问题。对于您的情况,选项2可能是最好的,因为它遵循了“偏好组合而非继承”原则。也就是说,您的请求对象“包含”了您需要的vm属性。@JohnPeters我使用的是EF、域模型模式和存储库模式。您能解释一下如何在UI层中使用强类型而不是视图模型吗?(如果我没听错的话)。谢谢。+1很好地解释了有效的问题。如果您添加了一些代码示例(非常简单),可能会更容易理解。@SBirthare谢谢:)是的,我通常会在问题中加入代码,但今天急于把问题提出来。@Thomasvei我在整个设计中都使用EF Poco类。所有这些都是关于数据的,数据很容易建模为POCO类,即使在SQL层也能理解这些类。ViewModel只是根据用户对他们想要做什么的响应启动适当的查询。这使得控制器除了提交帖子之外几乎没有任何逻辑。这就是为什么我所有的虚拟机都有一个名为Post的方法。Post方法不需要任何参数。传入,因为所选值已绑定到属性且已存在。