Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validation of domain model: how and where

A typical EF+MVC system will have two or three levels of validation:

  1. For ViewModel: input / physical validation (DataAnnotations, FluentValidation), in other words, length, null, range, regex, etc.
  2. For Model: input / physical validation (repeat of 1 in case MVC is not used and data comes from another system, WCF, forms, etc.)
  3. For Model: logical / "business rules" validation

I can't find best practices for validation of 2+3 for the actual Model / entities / domain / "business rules". We either:

  • put simple validation rules in an entity's property setter (but this is really messy)
  • hook into EF's SaveChanges(), and if an entity is in the Added or Modified state then trigger validation (which validates the entire entity at once)

This is hard to maintain. A lot of thought went into ViewModel validation, but for Model validation it is domain-specific and so it is for you to determine a creative solution, and mine is not that great.

  • Are there better ways to do this, or helpful tools (like maybe DataAnnotations or FluentValidation but for domain entities)?
  • Where is the best place to do model validation or to trigger the model's validation?
like image 821
Bobby B Avatar asked Oct 11 '12 05:10

Bobby B


1 Answers

A typical MVC+EF system will have 3 layers, but they aren't what you're talking about.

  1. Presentation Layer (input/output)
  2. Business Layer (Logical layer)
  3. Data Layer (model represents low-level data)

MVC provides validation for layer 1. EF provides validation for layer 3. There is no validation functionality provided by either MVC or EF for layer 2. If you want validation there, you have to do it yourself, or use a third party business object framework.

Validation in layers 1 and 3 are separate, even though in many cases they may have similar validation. The reason is that validation is accomplished in different ways, and with different requirements.

For example, you may have a field in your database that is nullable for data modeling or business logic reasons (let's say some data is pre-loaded and the user is required to update the field as part of the business process). The data layer says it's nullable, but you want your UI to make it required.

EDIT:

Simply put, the Data model should not be enforcing business rules. Therefore, you should not need any validation in the data model, other than to validate against the physical data model (ie, if the field is nullable, the data type in the model should nullable, otherwise not). In most cases, you physically cannot insert invalid (from the data models perspective) data because the code model will not allow it. The only exception to this is string variables, which can obviously overflow the size constraints of the physical model, but if that happens then an exception gets thrown anyways.

Your middle tier, the business layer, should be where you need to validate business rules (for example, that a customer purchase order must start with a letter). Neither MVC or Entity Framework, or WCF or whatever provide any way to do this validation.

There is a bit of a disconnect here, because the business rules should (in theory) drive the presentation layer validation. But, MVC has no built-in functionality to do that, though. So you end up duplicating your business rules in the UI.

There is at least one third party business object framework that tries to deal with this. CSLA. They provide a custom MVC model binder that ties in the business objects with the UI to do validation, but this is just using the built-in extendibility of MVC to do this.

So, if you don't want to use a dedicated business object framework, you are stuck either duplicating validation between UI and Business layer, or trying to figure out your own way to make your own business layer control UI validation.

like image 150
Erik Funkenbusch Avatar answered Oct 23 '22 18:10

Erik Funkenbusch