Fluent Validation, Domain and ViewModels - asp.net-mvc

I've been developing a web application with asp.net mvc, nhibernate and ddd concepts.
I've developed validations with Fluent Validation for my domain classes and it works fine. Well, now, I need a ViewModel to edit an entity in a View, soo, my question is, Do I need to create another validation class to validate my viewmodel? Or what should I do to get around this situation?
I ask it because I don't want to broke the DRY (don't repeat yourself) concetp.
Thanks!

Domain level validation, and View-Model validation are quite different imho (although they can have lots of overlap).
For instance, it may be perfectly allowable to have a certain field as null in your database, but require it's input on certain webforms. In this case you would check for null within the Model validation.
It would also be quite normal for multiple client applications to share the same Domain controllers (via WCF for example), but to possess different application validation logic.
If you use DataAnnotations in your view model you can get client-side javascript validation for free, so as a general rule, I always have a separate ViewModel from my Domain objects, even if it's a 1:1 mapping - I just use AutoMapper to translate between them. In addition to getting the client-side validation, it also reduces the clutter within the Domain validation.

Related

Validation of domain model: how and where

A typical EF+MVC system will have two or three levels of validation:
For ViewModel: input / physical validation (DataAnnotations, FluentValidation), in other words, length, null, range, regex, etc.
For Model: input / physical validation (repeat of 1 in case MVC is not used and data comes from another system, WCF, forms, etc.)
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?
A typical MVC+EF system will have 3 layers, but they aren't what you're talking about.
Presentation Layer (input/output)
Business Layer (Logical layer)
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.

ASP.NET MVC: ViewModels versus Domain Entities

I'm building a concept application with MVC 3 in an attempt to learn its ways. I've previously done some very heavy-duty applications in WebForms, using an n-tier approach, usually consisting of domain objects with repositories for storage and services to manipulate them before storage.
I'm trying to reconcile how I used to do things with the "right" way to do them in MVC, if there is any one such way. The thing I'm getting hung up over right now is when to use ViewModels versus when to use my domain objects that are in a whole other project. Validation is done with ViewModels, but as I write more customized, business-logic validation, it seems like it's too much responsibility on a lowly ViewModel that was just there to help me move data around before storing it officially in the database through the repository layer.
I'm also getting tired of mapping ViewModel data to the "official" domain object that the repository stores and retrieves, but I feel like I shouldn't tarnish my domain objects with the MVC attributes for validation, either.
Do you have any advice for where to draw the line between domain objects and mere ViewModels? Or am I complicating things, and my ViewModels should actually be the "official" models that the repository stores?
Do you have any advice for where to draw the line between domain objects and mere ViewModels?
Personally I always use View Models. All UI validation logic is done on the view models (required fields, ...) and business logic on the domain models (username already exists, ...). I also use AutoMapper in order to not get tired of mapping between the domain models and the view models that are passed to the view.
I generally default to using View Models, though for read-only views, I have been known to use the domain model (no reason to go through the overhead of mapping if I am only going to read data out of it).
If you do decide to use domain models, I would never let MVC bind directly to them, because if someone knows your domain well enough, they can post values that bind to properties you do not want the user to be able to edit. You can define white and black list of properties of what model binder can and cannot bind to, but utilizing that is something else you'll have to maintain and something that can easily be forgotten about.
I think the best approach is to use view models ALWAYS. These are about presentation concerns and should be where basic input validation is handled. Domain objects are not appropriate for this.
I use specific view models per view and only include the information that is needed in the view - keeping view models totally view-centric makes for nice clean views.
You can use Automapper to help remove the drudgery of moving between view and domain models.
Can I recommend ASP.NET MVC 2 in Action as a great book for strong ASP.NET MVC patterns. This covers using Automapper in detail.
Domain models and ViewModels will look very much like each other. However, ViewModels usually contain view logic attributes and properties. Also sometimes data type can be different, for example you might need to define a DateTime property as string just get the validation working without raising any errors.
I am using AutoMapper to convert from Model to ViewModels/vice versa.
ViewModel are good but don't forget Validation attributes are not only limited to MVC projects, you can use them in any .net project. Because of this it can make sense to apply the validation attributes to your domain objects, preferably by using a partial class and/or a Validator class http://weblogs.asp.net/scottgu/archive/2010/12/10/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3.aspx
My approach is that a ViewModel model should be associated to a single view (or least a set of related views), and is usually a sub-set of your domain model. I see a ViewModel as responsible for UI validation, where as your domain object is responsible for business rule validation.
As for mapping between the two, highly recommend using Automapper which can automatically map properties based on conventions, it's a huge time saver.

Multiple MetadataType validation rule sets using DataAnnotations with ASP.Net MVC

I am using DataAnnotations and MetadataType in ASP.Net MVC to validate the creation of one of my custom objects through a form on our www site. It's working really well.
But now we also need to be able to create the same object through a form in our internal admin site.
However, the validation rules are slightly different in that some fields are mandatory on the www site that are not mandatory when we complete the form ourselves through our internal admin system..
Further, I'd like to be able to give the same field different DisplayNames and different validation messages depending on which site/form the data is being collected from etc.
How can I essentially have two different MetadataType's and specify which one I wish to use when validating within the admin site, versus the www site.. I.e. two different sets of validation rules and the ability to specify which one I am validating against..
I have employed my MetadataType's using Buddy (partial) classes, as my objects are auto-generated by LINQ to SQL.
This might be of some help:
http://andrewtwest.com/2011/01/10/conditional-validation-with-data-annotations-in-asp-net-mvc/
I have been in the same situation before. I searched around at the time but found that there was no solution that would give you two sets of validation rules on the same class.
The way I tackled it was to use the view models. You have your "core" model classes and you want different UI's (in this case web and admin UI's) to have different validation rules. You wouldn't need buddy classes for your model classes in this case as you don't want to apply validation rules on the model class itself, instead you will need to inherit from your model class to create two view model classes, one for web and the other for admin interface, and apply the validation rules using DataAnnotations differently on those classes as per your needs. You can also "enhance" your view model classes with any extra, UI specific, attributes.
I know this solution is not perfect as you will have your validation rules on two different places and it's usually not advisable but it works and it's not that bad practically especially if the application isn't very large. The only other solution is to check manually the place user is using is coming from (web or admin) and then adding model state errors according to that. But I wouldn't recommend doing it that way.
I would love to hear if somebody has a better solution for this.

Using ViewModel in ASP.NET MVC with FluentValidation

I am using ASP.NET MVC with Entity Framework POCO classes and the FluentValidation framework. It is working well, and the validation is happening as it should (as if I were using DataAnnotations). I have even gotten client-side validation working. And I'm pretty pleased with it.
Since this is a test application I am writing just to see if I can get new technologies working together (and learn them along the way), I am now ready to experiment with using ViewModels instead of just passing the actual Model to the view. I'm planning on using something like AutoMapper in my service to do the mapping back and forth from Model to ViewModel but I have a question first.
How is this going to affect my validation? Should my validation classes (written using FluentValidation) be written against the ViewModel instead of the Model? Or does it need to happen in both places? One of the big deals about DataAnnotations (and FluentValidation) was that you could have validation in one place that would work "everywhere". And it fulfills that promise (mostly), but if I start using ViewModels, don't I lose that ability and have to go back to putting validation in two places?
Or am I just thinking about it wrong?
Or am I just thinking about it wrong?
Probably ;)
If you add all the validation code to your ViewModels you'd just be validating them instead of your actual Models. All your really changing is which objects can enter an invalid state.
Right now I'm happy as pie only validating ViewModels and then passing that information back to the actual Models and DAO layers. Whether or not your domain can enter an invalid state is a contentious topic though but so far this technique is working great for me. Validation in one place and no invalid objects in my persistence store.

Proper way to validate model in ASP.NET MVC 2 and ViewModel apporach

I am writing an ASP.NET MVC 2 application using NHibernate and repository pattern. I have an assembly that contains my model (business entities), moreover in my web project I want to use flattened objects (possibly with additional properties/logic) as ViewModels.
These VMs contain UI-specific metadata (eg. DisplayAttribute used by Html.LabelFor() method).
The problem is that I don't know how to implement validation so that I don't repeat myself throughout various tiers (specifically validation rules are written once in Model and propagated to ViewModel).
I am using DataAnnotations on my ViewModel but this means no validation rules are imposed on the Model itself. One approach I am considering is deriving ViewModel objects from business entities adding new properties/overriding old ones, thus preserving validation metadata between the two however this is an ugly workaround.
I have seen Automapper project which helps to map properties, but I am not sure if it can handle ASP.NET MVC 2 validation metadata properly. Is it difficult to use custom validation framework in asp.net mvc 2?
Do you have any patterns that help to preserve DRY in regard to validation?
It is fine to repeat validation. Trick is to place it where it's appropriate.
In your case - at UI, validate UI logic (view model props must not be null, in correct format etc.), in business layer - validate business logic (account has money etc.).
Do not use DRY as an excuse to violate SRP! :P
View models are supposed to uncouple your business layer from presentation role.
Don't glue everything together again.
I guess Automapper can't handle that. :)

Resources