5
votes

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?
1
I don't understand your "levels". What do you mean by "physical validation"? I don't understand what the difference is between 1 and 2. Are you referring to client-side and server-side validation? There is no middle "logical layer" validation system in MVC, in fact MVC doesn't provide any functionality for that. There is validation at the data layer though, which validates against the data model (which is not a logical model)Erik Funkenbusch
My question is not specifically concerned with client/server. 1 means validating input: null/length/range/etc. Then 2 is the same thing, but what if the data came from WCF or another system, then 1 didn't happen so you would perform input/physical validation AGAIN to be safe. Ignore all that, what I really need to understand is how people are doing 2+3 for the domain.Bobby B
Your premise is wrong, therefore your questions based on that premise is wrong. MVC does not provide any validation for the model. It only provides validation for the view model. EF provides validation for the Data model. The business layer or domain model is outside of either EF or MVC and is entirely under your control as to how to do validation.Erik Funkenbusch
My premise is not wrong. I specifically explained this has nothing to do with MVC in particular. We use the data layer in our MVC system, as well as in a non-MVC system. I need to know how to validate the data layer, in an automatic and elegant way as is done for MCV's ViewModels.Bobby B
Nothing stops you from using FluentValidation in your business logic.Erik Funkenbusch

1 Answers

6
votes

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.