MVC Validation and business layer - asp.net-mvc

The DataAnnotations validation happens in the default model binder and most of the examples I've seen uses the Model.IsValid in the Controller to verify if a model is valid or not. Since my controller action calls a business layer method and I like to validate the entity there:
Do I have to explicitly switch off
the model binder validation?
How do I validate the entity in the
business layer. In other words, how
do I trigger validation given an
object?
Also, I am using View Models. Do I
add the validation attributes to the
view model? If so, since View models
are being tied to the UI, what about
validation at the business layer??

I'm gonna start by answering your question #3: yes, when using view models, add Data Annotation validation attributes right on the properties on your view model. As you pointed out, the view models are tied to the UI so they have presentation concerns and the validation is strictly for UI input validation. The validation attributes you apply here will be automatically invoked by the framework and you can check ModelState.IsValid in your controller (which you also pointed out).
In reference to validating objects in your business layer, there are numerous ways to do this. For example you could also use data annotations on your business layer domain model entities as well. You could also use other frameworks like Enterprise Library validation application block, Fluent Validation, etc. But in this case, you're probably going to be making an explicit call to validate your domain objects (and each of these frameworks has their own mechanism for doing so). I'm presuming your mapping between your view models and domain models (probably with something like AutoMapper) given your description above.
Having said all that, in reference to your question #1, I would not switch off model binder validation. Let that performance the validation on your view models as normal. Map your view models to your domain model classes. Then feel free to perform an additional layer of business object validation for your domain model. You may not even doing this validation in the MVC project - this might be encapsulated in a business layer that you have somewhere else in your app.

Related

Is creating ViewModel for Model validation odd and unnecessary?

Is there any good reasons to create ViewModel that copy`s Model with addition of validation logic?
Why not simply extend current model with validation logic?
If you will create ViewModel copy, you need to
Create class with corresponding fields (which is not big problem if you have few models to validate, but what if you have many..)
Set automapper, wich can be slow, and adds additional logic to your solution (or do it by hand, which is probably, bad idea)
Support Model changes for ViewModel
These problems dissapear if you simply extend your basic Model. So why it is so popular to create ViewModel layer?
You can have two views with different validation logic for the same model.
the classic example is a sign up form, with a single page form vs a multi page wizard.
In both cases the model is the same, but in the wizard view its legitimate to submit the model half filled in, while the single page version should have all the fields validated.
Taking this possibility further leads to the one viewmodel per view methodology. Where you always make a viewmodel for a view as a matter of course because you expect to need the flexibility that it offers as a general thing.
Additionally, its pretty rare that view exactly matches a model. You usually require more than one model plus some odd extra bits. eg user model for the 'logged in as' header, list of models to display plus pagination info.
You can avoid some of the issues you mention by using ViewModels which simply wrap models and expose their properties where extra logic isn't required

entity framework POCO + recommended patterns

We do like EntityFramework (CTP5) quite a lot and Using it along with ASP.NET MVC3.
What I dislike is;
things are mixed in together.
I can place a DisplayAttribute, RequiredAttribute, RangeAttribute, CompareAttribute together in the same class which means I am mixin in database validation, some business logic and UI alltogether. I can even place ScriptIgnore attribute to customize it as a Json DTO object. So I can use the same POCO class for Persistance, Presentation, DTO and Business Object, and as my domian model.
Which design patterns do you follow along with EF POCO + MVC3 toolset. What layers do you have?
What resposibilities do you add to your classes (Is Your POCO class also your Domain Model)
I use View Models to solve this problem. Validation and UI presentation attributes go to the view model. In this pattern the controller uses a repository to fetch an EF model, maps this EF model to a view model (I use AutoMapper for this) and passes the view model to the view. Because the view model contains all the UI presentation attributes the view behaves as expected. Each view must have its own view model. This means that you could have multiple view models associated to the same EF model but contain a different subset of properties and display formatting attributes based on the specific requirements of the view.
The process works the other way around as well: the controller receives a view model from the view as argument. It maps the view model back to a model and passes the EF model to the repository. UI validation attributes are handled on the view model because you could have different validation requirements in different views: think for example Insert/Update views. In the insert view you will be creating a new entity thus the Id property won't be required. You won't even have an Id property on your view model in this case. In the update view on the contrary the Id property will be required.
My POCO classes are almost always domain models and almost never view models so I don't have these problems.
The best practice is to use special "view model" class when passing data from controller to view (or as JsonResult). In such case you mark UI based attributes in that view model. In most cases (except pure crud applications) you need to display something more or something less then your domain object so you still need some view model (unless you use ViewData directly).
Data annotations on domain object makes sense only if you want to use them for business/data level validation which can take different rules then UI validation.
If you want to follow strict DDD where POCO classes are domain objects = offers methods performing domain logic on instance of object you should go even further because in such case your business facede should not expose domain objects to controller. In such case you will end up with data transfer objects exposed on business facade and consumed in controller. I'm not purist so in this scenario I'm open minded to using data annotations on DTOs directly but it depends on another requirements.

Domain object validation vs view model validation

I am using ASP.NET MVC 3 and I am using FluentValidation to validate my view models. I am just a little concerned that I might not be on the correct track. As far as what I know, model validation should be done on the domain object. Now with MVC you might have multiple view models that are similar that needs validation. What happens if a property from a domain object occurs in more than one view model? Now you are validating the same property twice, and they might not even be in sync. So if I have a User domain object then I would like to do validation on this object. Now what happens if I have UserAViewModel and UserBViewModel, so now it is multiple validations that needs to be done.
In my News class I have a property called Title, which is a required field. On my view model I also have a Title property, I use AutoMapper to map the News and NewsViewModel. So this validation is happening twice. When does domain model validation occur and when does view model validation occur?
The scenario above is just an example, so please don't critise on it.
It's a subtle distinction but the validation on your view model is to validate correct user input and forms an anti-corruption layer for your domain model, whereas the "validation" on your domain model enforces business rules. It is perfectly normal and you should have validation on both layers. In fact it may be feasible that UserAViewModel has slightly different input validation from UserBViewModel. As for your question, generally I try to avoid exposing domain objects through my ViewModel and instead map between them (often using something like AutoMapper), that way your ViewModels truly are anticorruption layers rather than property bags of domain models. Hope that helps.
What happens if a property from a
domain object occurs in more than one
view model?
This shouldn't happen. View models should be totally divorced from your domain.
Does this answer your question?

ASP.NET MVC: using EF entities as viewmodels? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
ASP.NET MVC - Linq to Entities model as the ViewModel - is this good practice?
Is is OK to use EF entities classes as view models in ASP.NET MVC?
What if viewmodel is 90% the same of EF entity class?
Let's say I have a Survey class in Entity Framework model. It 90% matches data required for view to edit it.
The only difference from what view model should have - is one or several properties to be used in it (that are required to populate Survey object because EF class cannot be directly mapped onto how it's properties are represented (sub-checkboxes, radio groups, etc.))
Do you pass them using ViewData[]? Or create a copy of Survey class (SurveyViewModel) with new additional properties (it should be able to copy data from Survey and back to it)?
Edit:
I'm also trying to avoid using Survey as SurveyViewModel property. It will look strange when some Survey properties are updated using UpdateModel or with default binder, while others (that cannot be directly mapped to entity) - using SurveViewModel custom properties in controller.
I like using Jimmy Bogard's approach of always having a 1:1 relationship between a view and a view model. In other words, I would not use my domain models (in this case your EF entities) as view models. If you feel like you are doing a lot of work mapping between the two, you could use something like AutoMapper to do the work for you.
Some people don't like passing these model classes all the way through to the view, especially as they are classes that are tied to the particular ORM you're currently using. This does mean that you're tightly binding your data framework to your view types.
However, I have done this in several simple MVC apps, using the EF entity type as the Model for some strongly-typed views - it works fine and is very simple. Sometimes simple wins, otherwise you may find yourself putting a lot of effort and code into copying values between near-identical Model types in an app where realistically you'll never move away from EF.
You should always have view models even if they are 1:1. There are practical reasons rather than database layer coupling which I'll focus on.
The problem with domain, entity framework, nhibernate or linq 2 sql models as your view classes is you cannot handle contextual validation well. For example given a user class:
When a person signs up on your site they get a User screen, you then:
Validate Name
Validate Email
Validate Password Exists
When an admin edits a user's name they get a User screen, you then:
Validate Name
Validate Email
Now expose contextual validation via FluentValidation, DataAnnotations Attributes, or even custom IsValid() methods on business classes and validate just Name and Email changes. You can't. You need to represent different contexts as different view models because validation on those models changes depending on the screen representation.
Previously in MVC 1 you could get around this by simple not posting fields you didn't want validated. In MVC 2 this has changed and now every part of a model gets validated, posted or not.
Robert Harvey pointed out another good point. How does your user Entity Framework display a screen and validate double password matching?
On bigger projects, I usually split up business objects from data objects as a matter of style. It's a much easier way to let the program and database both change and only affect the control (or VM) layer.

When to use a ViewModel rather than a Model?

I have a business model called Customer which has many required properties (via DataAnnotations) and other validation rules.
I have a View which is meant to allow editing of the customer's address fields.
The problem I have is that I want a strongly-typed view but I can't get away with using the Customer type here. Since the view will only be editing address data it won't return any of the other required data the Customer object would need in order to validate.
This suggests that I should use a ViewModel. However, there are many business rules that apply to the address related properties on Customer that I would have to duplicate on the new ViewModel (address lengths, zipcodes, state formatting, etc). They need duplicated because the client-side validation (I'm using xVal) requires that information in order to function.
I feel I've reached a catch-22 scenario. DRY tells me that I should not duplicate my business rules on a ViewModel that my Model already has, but on the other hand I can't use the Model because it will never validate.
What is the best practice in this situation?
The chosen path
The solution I ultimately chose was the ViewModel path. In order to get the validation I needed to work there was simply no other practical way.
However, was was unable to eliminate some rough spots using the ViewModel brought up. I refactored some of my models to use interfaces containing the properties I knew would re-used in the ViewModels. Since the ViewModels could now use the same interfaces as the models it allowed me to do things like this:
public ActionResult Edit(AddressViewModel address)
{
if(!ModelState.IsValid)
return View();
var customer = Customer.Load(address.CustomerId);
UpdateModel<IAddress>(customer);
// more stuff ....
}
This saves me the step of using an automapper.
The answer I selected below (by Wyatt Barnett) I felt was good for most cases and I use it on other projects I have, especially useful with Linq-to-Sql.
I ran into the same issue with complex model classes not playing well with simpler views and model binding. I also happened to be using xVal. The trick I fell upon was to use Validation Buddies to cover the DRY angle for basic validation then use AutoMapper to push things back into the full-blown model classes. I can then run a second round of server-side validation to cover the more complex bits that require access to the database and such.
From a technical standpoing, your view should only talk to your ViewModel, not the model. So your viewmodel should delegate all the validation to the model. The ViewModel should be adding interaction layer stuff.
Of course this all falls apart in Silverlight, where you typically need some kind of quick validation done at the client side, so all of a sudden you're copying all your validation rules up to the ViewModel anyway. I haven't figured a way around that yet.

Resources