ASP.NET MVC ModelMetadata - 当我们在模型上添加属性来描述 UI 时,是否违反了关注点分离?
通过将 UI 帮助器属性放在模型对象上 (DisplayFormat< /a> 或 UIHint)我们不是吗耦合模型和视图?
According to this blog post "ModelMetadata objects are constructed with data taken from attributes, primarily from the System.ComponentModel and System.ComponentModel.DataAnnotations namespaces."
By putting UI helper attributes on Model objects (DisplayFormat or UIHint) aren't we coupling Model and View?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我相信是这样。就我个人而言,我让我的模型完全与 ui 无关,并且我编写 ViewModels,它将在我的视图中代表我的模型。然后将所有注释分配给这些 ViewModel。
我认为违规是因为这限制了您重用模型的能力,因为您基本上是在模型中定义视图行为。
I believe so. Personally I keep my model completely ui-agnostic and I write ViewModels which will represent my model in my View. Then assign all annotations to these ViewModels.
I think the violation comes from the fact that this limits your ability to reuse your model, since you are basically defining view behavior in your model.
我想是的。
我创建了特定的视图模型类来表示浏览器和服务器之间的信息交换。如果模型状态有效,则我复制这些值或使用这些值调用域方法(这就是 Models 文件夹的用途)。我从未将 MVC 特定属性放在我的域实体上。
根据经验,我将实体保存在一个单独的程序集中,该程序集对 MVC 一无所知。
小心在 MVC 操作方法中公开域实体...模型绑定器可能会给您开一个糟糕的玩笑:D 例如,如果您有一个类“Account”,其属性为“IsAdmin”,并且您在注册表单中,用户可以尝试在 GET 字符串或 POST 负载中传递任意“IsAdmin=true”参数,MVC 模型绑定器将在您的模型中设置该属性...并且您的代码可能会保存该信息在数据库中。
因此,我认为关注视图模型非常重要。
我知道,有了像 ViewBag 这样的“动态”东西,让你自己的 LINQ 实体成为操作方法中的参数,一切都变得很容易做到……但我们不应该忽视安全性,为了强制执行安全性,我们必须确保只有我们想要的信息才能到达我们的域。
干杯。
I think so.
I create specific view model classes that represent the information exchange between browser and server. If the model state is valid, then I copy the values or call the domain methods with those values (that's what the Models folder is for). I never put MVC specific attributes on my domain entities.
Rule of thumb, I keep my entities in a separate assembly, that knows nothing about MVC.
Watch out with expose domain entities in your MVC action methods... the model binder could do you a bad joke :D If for example, you have a class "Account", with a property "IsAdmin" and you expose this entity in a registration form, the user could try to pass an arbitrary "IsAdmin=true" parameter in the GET string or in the POST payload, and the MVC model binder will set that property in your model... and your code will probably save that information in the database.
Therefore, I think is very important to keep attention on the view models.
I know that with all this "dynamic" stuff like the ViewBag and let your own LINQ entities be parameters in the action methods everything becomes very easy to do... but we shouldn't overlook security, and to enforce security we have to be sure that only the information we want can arrive to our domain.
Cheers.
这很大程度上取决于您如何定义“耦合”。从某种意义上说,您已经将视图“耦合”到模型:您的视图使用模型定义的相同属性。问题不在于“耦合”,而在于“什么”和“如何”。模型描述什么(应该显示),由视图定义如何(执行)。如果你想严格遵循这个原则,你应该放弃UI提示。
如果您想要更实用,有时这些属性可以简化您的视图(通常会变得太复杂)。所以,这取决于你。
如果您想让模型可重用(在大多数情况下这不是一个好主意,但我们不要在这里教条主义),请确保仅使用在整个应用程序中一致的属性。例如,如果您以相同的方式显示所有浮点数,则将 DisplayFormat 属性放在模型上是有意义的,而不是在视图中一次又一次地键入它,从而用无聊的细节污染它们。
我倾向于将一般结构放在主视图中,并将细节委托给部分视图,UIHint 属性对我帮助很大。称之为耦合,但好处是巨大的。
That largely depends on how you define "coupling". You have already "coupled" your View to your model in a sense: your View uses the same properties that your Model defines. The problem is not with "coupling" it's about "what" and "how". The Model describes the What (should be displayed), it's up to the View to define the How (to do it). If you want to strictly follow this principle, you should discard the UI hints.
If you want to be more practical, sometimes these attributes can simplify your Views (that often get too complicated). So, it's up to you.
If you want to make your model reusable (which is in most cases not a good idea, but let's not get dogmatic here), make sure that you use only attributes that are consistent across the application. For example, if you display all floating point numbers in the same way, it makes sense to put the DisplayFormat attribute on the model, rather than type it again and again in your Views, polluting them with the boring details.
I tend to put the general structure in my main View and delegate the details to the partials, the UIHint attribute helps me a lot. Call it coupling, but the benefit is just huge.