Adr*_*ore 11 architecture validation asp.net-mvc xval automapper
当我开始使用xVal进行客户端验证时,我只实现了使用域模型对象作为viewmodel或viewmodel中这些对象的嵌入实例的操作方法.
这种方法在大多数情况下都能正常工作,但有时候视图需要显示和回发模型属性的一个子集(例如,当用户想要更新他的密码,而不是他的其他配置文件数据时) .
一个(丑陋的)解决方法是在表单上为每个属性设置一个隐藏的输入字段,该字段在表单上不存在.
显然,此处的最佳做法是创建一个自定义视图模型,该视图模型仅包含与视图相关的属性,并通过Automapper填充视图模型.它更清晰,因为我只传输与视图相关的数据,但它远非完美,因为我必须重复已经存在于域模型对象上的相同验证属性.
理想情况下,我想通过MetaData属性将域模型对象指定为元类(这通常也称为"伙伴类"),但这不起作用,因为当元数据类具有属性时,xVal会抛出视图模型中不存在.
这有什么优雅的解决方法吗?我一直在考虑攻击xVal源代码,但也许还有其他方法我到目前为止忽略了.
谢谢,
阿德里安
编辑:随着ASP.NET MVC 2的到来,这不仅仅是与验证属性相关的问题,而且它也适用于编辑器和显示属性.
这是您的输入屏幕不应与模型紧密耦合的典型原因.这个问题实际上会在MVC标签上弹出一个月大约3-4次.如果我能找到上一个问题并且这里的一些评论讨论很有意思,我会欺骗.;)
您遇到的问题是您试图将模型的两个不同验证上下文强制转换为在大量场景下失败的单个模型.最好的示例是注册新用户,然后让管理员稍后编辑用户字段.您需要在注册期间验证用户对象上的密码,但不会向管理员显示密码字段以编辑用户详细信息.
绕过这些的选择都是次优的.我现在已经为3个项目解决了这个问题,并且实施以下解决方案从未干净过,而且通常令人沮丧.我将尝试实践并忘记所有其他人正在讨论的DDD/db/model/hotness.
1)多视图模型 具有几乎相同的视图模型违反了DRY原则,但我觉得这种方法的成本非常低.通常违反DRY放大维护成本,但恕我直言,这是最低的,并不是很多.假设您不会更改LastName字段可以经常使用的最大数字字符数.
2)动态元数据 MVC 2中有一些钩子,用于为模型提供自己的元数据.使用这种方法,您可以使用任何用于提供元数据的内容,根据当前的HTTPRequest以及Action和Controller排除某些字段.我已经使用这种技术构建了一个数据库驱动的权限系统,该系统进入数据库并告诉DataAnnotationsMetadataProvider的子类排除存储在数据库中的属性.
这种技术工作得非常好,但唯一的问题是验证UpdateModel().为了解决这个问题,我们创建了一个SmartUpdateModel()方法,该方法也会进入数据库并自动生成exclude string []数组,以便不验证任何不允许的字段.我们当然是出于性能原因而缓存它,所以它还不错.
只是想重申我们在模型上使用[ValidationAttributes],然后用运行时的新规则来超越它们.最终结果是,[Required]如果用户没有访问权限,则不验证User.LastName字段.
3)疯狂的接口动态代理事件
我尝试的最后一种技术是使用ViewModels的接口.最终的结果是我有一个继承自IAdminEdit和等接口的User对象IUserRegistration.IAdminEdit和IUserRegistration都包含DataAnnotation属性,这些属性执行所有特定于上下文的验证,如带有接口的Password属性.
这需要一些hackery,而且比其他任何东西都更像学术活动.2和3的问题是需要自定义UpdateModel和DataAnnotationsAttribute提供程序以使其了解此技术.
我最大的绊脚石是我不想将整个用户对象发送到视图,所以我最终使用动态代理来创建运行时实例 IAdminEdit
现在我明白这是一个非常xVal的具体问题,但是所有通往动态验证的道路都会导致内部MVC元数据提供商的定制.由于所有元数据都是新的,因此此时没有什么是干净或简单的.您必须做的工作来定制MVC的验证行为并不难,但需要深入了解所有内部工作的方式.
| 归档时间: |
|
| 查看次数: |
2097 次 |
| 最近记录: |