MVC、ViewModel 和验证

发布于 2024-10-09 19:05:39 字数 302 浏览 3 评论 0原文

我正在使用 POCO 创建带有 EF4 的 MVC3 应用程序。我已向我的 EF 实体添加了验证属性。现在,当我构建视图时,我想使用视图模型(也许使用 AutoMapper 来填充它们)。

我遇到的问题是我必须在视图模型上重新定义验证属性,这违反了 DRY 原则。例如,如果我决定更改字段的大小,则必须更改 POCO 和使用它的任何视图模型上的 MaxLength 属性。

是否有一些棘手的方法可以将验证规则从 POCO 映射到视图模型?

I'm creating an MVC3 application with EF4 using POCOs. I've added validation attributes to my EF entities. Now, as I'm building the views, I want to use a view model (and perhaps use AutoMapper to fill them).

The problem that I have run into is that I have to redefine my validation attributes on my view model which violates the DRY principal. For example, if I decide to change the size of a field, I have to change the MaxLength attribute on both the POCO and any view models that use it.

Is there some tricky way I can map the validation rules from my POCOs to my view model?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栀梦 2024-10-16 19:05:39

我个人在视图模型中执行验证。这是控制器从视图接收的内容,它是包含用户输入的类。我区分两种类型的验证规则:表面验证和业务验证。应在视图模型中强制执行必填字段、正确格式等规则,而应在模型上验证数据库中已存在的具有给定名称的用户等业务规则。

此外,您还可以将不同的视图模型映射到同一模型,但基于视图验证规则可能会有所不同。因此,您在视图模型上不会有完全相同的验证规则。

Personally I perform validation at view models. This is what a controller receives from a view and it is the class which contains the user input. I distinguish between two type of validation rules: surface validation and business validation. Rules such as required fields, proper formats should be enforced at the view models whereas business rules like a user with a given name already exists in the database should be validated on the model.

Also you could have different view models mapped to the same model but based on the view validation rules could vary. Because of this you won't have exactly the same validation rules on the view models.

你是我的挚爱i 2024-10-16 19:05:39

获得一些抽象的一种方法是让 ViewModel 由您的业务模型类“组成”,包括您需要的其他视图信息。

class MyObject 
{
    public int ID {get;set}

    [Required]
    [StringLength(512)]     
    public string Name {get;set;}

}

class MyViewModel // ViewModel for a specific view 
{
    public MyObject MyModel {get;set;}        // the model that is being edited 

    // other data the view might need, set by the controller 
    public string SomeMessage { get; set; }
    public List<SomeObject> SomeObjects {get;set;} /// e.g. for a drop-down list

}

然后在视图中相应地引用 ViewModel。

@model My.Namespace.MyViewModel


Hello @model.MyModel.Name !!!

这样,您只需在一处指定业务类中的验证和/或数据注释。

如果您想要进行不同的验证,那么将需要一些策略来有选择地应用验证逻辑。

One approach that gets some abstraction is to have a ViewModel 'composed' of your business model class, including other view information you need.

class MyObject 
{
    public int ID {get;set}

    [Required]
    [StringLength(512)]     
    public string Name {get;set;}

}

class MyViewModel // ViewModel for a specific view 
{
    public MyObject MyModel {get;set;}        // the model that is being edited 

    // other data the view might need, set by the controller 
    public string SomeMessage { get; set; }
    public List<SomeObject> SomeObjects {get;set;} /// e.g. for a drop-down list

}

Then in the view reference the ViewModel accordingly.

@model My.Namespace.MyViewModel


Hello @model.MyModel.Name !!!

This way, you only specify your validation and/or data-annotations in your business class in one place.

If you are wanting to have different validation then that will require some strategy to selectively apply validation logic.

意犹 2024-10-16 19:05:39

我也为此苦苦挣扎,我同意这违反了 DRY。我最近在此处发布了有关此问题的问题并受到了相当大的阻力。

在任何现实世界的应用程序中,您都不可能获得完美的 DRY。有时,违反原则比盲目遵守原则更能带来好处。

编辑:

人们可能还会认为 DRY 可能违反单一职责原则 (SRP)。通过重用类似的代码,您现在可以使代码执行不止一件事。如果您考虑到数据模型和视图模型具有不同的目的,因此具有不同的职责……将它们组合成单个模型违反了 SRP。也就是说,通过使数据模型也成为视图模型,这是两个不同的职责。

现在,人们可以想出多种方法来尝试协调 SRP 与 DRY 在这方面的关系,但在某些时候您必须权衡成本和收益。

I too struggle with this, and I agree that it violates DRY. I posted a recent question about this Here and got quite a bit of pushback.

You can't ever get perfect DRY in any real world application. Sometimes you get more good out of violating a principle than by trying to stick to it blindly.

EDIT:

One might also consider that DRY can violate the Single Responsibility Principle (SRP). By reusing similar code, you are now causing the code to do more than one thing. If you think about the fact that data models and view models have different purposes, and thus different responsibilities... combing them into a single model violates SRP. That is, by making your data model also be a view model, that's two different responsibilities.

Now, one can think of a number of ways to potentially try and reconcile SRP with DRY in this regard, but at some point you have to weigh the benefits from the cost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文