Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 哪个图层应该构建视图模型?_Asp.net Mvc_Viewmodel_S#arp Architecture - Fatal编程技术网

Asp.net mvc 哪个图层应该构建视图模型?

Asp.net mvc 哪个图层应该构建视图模型?,asp.net-mvc,viewmodel,s#arp-architecture,Asp.net Mvc,Viewmodel,S#arp Architecture,我在用电话。我不记得在哪里读过它,但我知道视图模型应该存储在服务层,您的视图应该将视图模型提交给服务进行处理 我的问题是:哪个层应该构建视图模型?它应该在服务层,由控制器请求吗?或者控制器应该自己构造视图模型吗?还有一个关于更新视图模型的问题,因为如果它包含集合,并且模型状态无效,则还需要重新调用任何列表 有什么建议吗?我在控制器内创建视图模型。控制器获取域实体(由模型绑定器从数据库检索),可能位于其他视图模型内,联系存储库以获取更多数据,创建新视图模型,并将其传递给相应的视图(或重定向)。所以

我在用电话。我不记得在哪里读过它,但我知道视图模型应该存储在服务层,您的视图应该将视图模型提交给服务进行处理

我的问题是:哪个层应该构建视图模型?它应该在服务层,由控制器请求吗?或者控制器应该自己构造视图模型吗?还有一个关于更新视图模型的问题,因为如果它包含集合,并且模型状态无效,则还需要重新调用任何列表


有什么建议吗?

我在控制器内创建视图模型。控制器获取域实体(由模型绑定器从数据库检索),可能位于其他视图模型内,联系存储库以获取更多数据,创建新视图模型,并将其传递给相应的视图(或重定向)。所以控制器的职责是根据输入的域数据准备视图/视图模型(当然还要处理错误)

您可以寻找在控制器中创建视图模型的替代方法。这种技术将视图模型创建移到动作之外,这样控制器动作不仅接受纯域对象,而且还返回纯域对象。我不认为这在所有情况下都是合适的,但学习起来很有趣


上述与AutoMapper相关的技术也提出了类似于“我是否应该将viewmodels传递给服务层”的问题。不,你没有。如果需要将复杂对象传递给服务层或域层,可以在适当的服务层/域层中定义此对象,并使用它将数据传递给这些层。然后可以轻松地将此对象映射到视图模型或从视图模型映射(例如,使用AutoMapper)。但您的下层(服务/域)不应耦合到上层(视图/控制器)。在这种情况下不是,在其他情况下也不是。永远不要让底层依赖于上面定义的内容。

这些文章可能会让您感兴趣:


有一个与第二篇文章相关的示例应用程序,它在服务层中包含视图和表单模型,而不是控制器。

另请看--它非常棒。该框架基于S#arp体系结构。它对查看/形成/编辑视图模型等有很多指导。

按照传统方法或理论,视图模型应该是用户界面(UI)层的一部分。至少名字是这么说的

但是,当您着手使用实体框架、MVC、存储库等来实现它时,您会意识到其他一些东西

必须有人将实体模型映射到ViewModels(最后提到的DTO)。这应该在A)UI层(由控制器)中完成,还是在B)服务层中完成

我选择选项B。选项A是否定的,因为几个实体模型组合在一起形成了一个ViewModel。我们可能不会将不必要的数据传递给UI层,而在选项B中,服务可以处理数据,并在映射(到ViewModel)后仅将所需/最小值传递给UI层

但是,假设我们使用选项A,我们将ViewModel放在UI层(实体模型放在服务层)

如果服务层需要映射到ViewModel,那么服务层需要访问UI层中的ViewModel。哪个图书馆/项目?Viewmodel应该位于UI层的一个单独的项目中,该项目需要由服务层引用。如果ViewModel不在单独的项目(.dll)中,则存在循环引用,因此无法使用。让服务层访问UI层看起来很尴尬,但我们仍然可以处理它

但是,如果有另一个UI应用程序使用此服务呢?如果有移动应用呢?ViewModel可以有多大的不同?服务是否应该访问相同的视图模型项目?还是所有的UI项目都会竞争

考虑这些因素后,我的答案是将Viewmodel项目放在服务层中。每个UI层都必须以任何方式访问服务层!而且可能有很多相似的视图模型,它们都可以使用(因此映射对于服务层来说变得更容易)。如今,映射是通过linq完成的,这是另一个优点

最后是关于DTO的讨论。以及ViewModels中的数据注释。带有数据批注的ViewModels不能驻留在服务层中。因此,DTO将是ViewModel的精确副本,在两者之间具有一对一映射(例如使用AutoMapper)。同样,DTO仍然具有UI(或多个应用程序)所需的逻辑,并且驻留在服务层中。UI层视图模型只是从DTO复制数据,并添加一些“行为”(例如:属性)

[现在这场讨论将有一个有趣的转折点,阅读…:I]

而且不要认为数据注释属性只适用于UI。如果使用System.ComponentModel.DataAnnotations.dll限制验证,则相同的ViewModel也可用于前端和后端验证(从而删除驻留在DTO中的UI ViewModel副本)。此外,属性也可用于实体模型中。例如:使用.tt,可以使用验证属性自动生成实体框架数据模型,以便在发送到后端之前执行一些数据库验证,如max length。另一个优点是,如果后端验证在DB中发生更改,那么.tt(读取DB细节并为entity类创建属性)将自动拾取该值。这也会迫使UI验证单元测试失败,这是一个很大的优点(因此我们可以纠正它并通知所有UI/消费者,而不是意外地忘记和失败)。是的,讨论正在向良好的框架设计迈进。正如您所看到的,所有这些都是相关的:分层验证、单元测试策略、缓存策略等等

尽管与这个问题没有直接关系。”ViewModel Façade(另一个ViewModel中的ViewModel)和本必看节目中提到的“command”也值得探索(@11:48开始)

I impleme