加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 为什么我们使用ViewModels?

发布时间:2020-12-16 00:25:46 所属栏目:asp.Net 来源:网络整理
导读:我最近已经开始作为网页开发人员工作。我使用ASP.NET MVC 4和NHibernate。 在我的工作场所,我们严格使用视图模型来在控制器和视图之间传输数据。并且视图模型不应该包含模型的任何对象。 我了解它是控制器和视图之间的一种层次。 但是,即使我们可以直接将
我最近已经开始作为网页开发人员工作。我使用ASP.NET MVC 4和NHibernate。

在我的工作场所,我们严格使用视图模型来在控制器和视图之间传输数据。并且视图模型不应该包含模型的任何对象。
我了解它是控制器和视图之间的一种层次。

但是,即使我们可以直接将模型的对象发送到视图(在大多数情况下),我也会发现编写viewmodel类是重复冗余的。

例如,如果我想显示一个订单,我可以在控制器的动作中做到这一点 –

return View(Repository.Get<Order>(id));

但是,我必须编写一个视图模型,用提取的顺序填充它,然后将其传递给视图。

所以,我的问题是,当我们可以使用模型的对象时,编写viewmodels的目的是什么?

解决方法

对于较小的项目,你是对的。我听到你的观点和同情 – 然而有很好的理由,这种粗暴和重复的工作,特别是在更大和更复杂的应用中:

>在控制器的操作中执行所有处理至关重要。但是,在您给出的示例中,Repository.Get方法可能会返回一个延迟评估的IQueryable对象,这意味着在评估视图之前不会打击数据块。由于种种原因,这是坏的。 (解决方法是在控制器中调用.ToList)。
>“视图不应包含任何非呈现逻辑”和“您不应该相信视图”(因为View可能是用户提供的)。通过提供一个Model对象(可能仍然连接到活动的DatabaseContext),视图可能会对您的数据库进行恶意更改。
>视图的数据显示并不总是以1:1与其模型的数据进行映射,例如考虑用户详细信息页面:

用户的EF Model对象表示其数据库中的实体,因此可能如下所示:User {UserId,UserName,PasswordHash,PasswordSalt,EmailAddress,CreatedDate},而“用户详细信息”页面上的字段将为User { UserId,UserName,Password,ConfirmYourPassword,EmailAddress},你看到区别吗? Ergo,您不能使用EF用户模型作为视图模型,您必须使用单独的类。

>模型操纵的危险:如果让ASP.NET MVC(或任何其他框架)将模型绑定到传入的HTTP POST Request,那么(以上面的用户详细信息示例),用户可以通过伪造UserId来重置任何人的密码属性值。 ASP.NET将在绑定期间重写该值,除非您特别对其进行清理(这将与使用个人ViewModels一样诡异),否则此漏洞仍将保留。
>在团队合作的多个开发人员的项目中,重要的是一切都一致。有一些页面使用定制的ViewModels而不是其他页面使用EF模型是不一致的,因为团队不会分享一个简洁的头脑,事情必须被记录在案,通常是有道理的。同样的原因,一个开发人员可以在没有将XML文档放在源代码中的情况下得到消除,但是在一个团队的情况下,如果没有的话,你会崩溃。

在你的情况下,我会与你分享一些轻微的解决办法,但请注意前提条件:

>您的意见可以完全信任
>您的观点只包含演示逻辑
>您的应用程序主要是CRUD
>您的意见与每个EF实体模型(即没有JOIN)对应1:1
>您的意见只处理POST表单的单一简单模型,而不是复杂模型(即对象图)

那么你可以这样做:

>将所有单向,非表单相关的数据放入ViewData集合中,或将MVC 4中的ViewBag(甚至是一个通用的ViewData< T>如果您是硬核的)。这对于存储HTML页面标题和与主页面共享数据非常有用。
>使用您的完全评估和加载的EF模型作为您的View< TModel>楷模。

但是请谨慎使用此方法,因为它可能会导致不一致。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读