I have the following architecture of my application:
http://clip2net.com/clip/m50879/1303228845-clip-15kb.png
The Model contains a set of POCO objects which should be validated on the web and the services sides.
Also, I have additional ViewModel layer which is being used only on the web side. The ViewModel layer contains the most of validation logic which is the same as the Model validation logic...
The question is:
What is the best approach to avoid copy-paste of the Model validation logic to the ViewModel validation logic?
Maybe this is of interest:
"How to: Validate Model Data Using DataAnnotations Attributes"
http://msdn.microsoft.com/en-us/library/ee256141(VS.100).aspx
Related
I have a edmx model done by Database First and generating the DBSet with the VS tools. I extended with partials the classes to add dataannotation validation to it.
I am receiving on my controller the view model which I am manually controlling the validation of fields. So eventhough I have a required field on my partial class, I am removing it once in my controller ModelState.Remove("pasajeros[" + count + "].numResidencia"); because of some conditions.
Before, I was using LINQTOSQL and I had no problems. But now Entity framework is not honoring my customization of ModelState.
How do i propagate or GO about this issue with EntityFramework?
thanks
Keep your view models and Entity models separate. Put your validation annotations on your view models. Then use a tool like Automapper to map the Entity to ViewModel fields for you.
On edit you validate your view model then update your Entity fields which you then save.
we are building an ASP.Net MVC application, and we ask ourselve the question where we shoud put the validation logic for incoming data.
We already have the simple validation in place: these are attributes on the viewmodel, like [required], [numeric] , [email] etc. (this is open for discussion too, btw)
But now we have some more input validation: we want to validate if the id's received from dropdownlists are genuine id's.
For example: when we receive 91 as a countryid, i have to make sure 91 is a valid countryid and not a value 'hacked into' the form by a user. Because if it is not a valid countryid, my datalayer generates an error.
Should i place this in the controllers action method, because that
method knows what is right and what is wrong when the data from the request arrives?
Should i place it in a VacancyValidator (the object is a Vacancy
object) where i put all validation logic for all vacancy related
viewmodels
Should i place it in the ViewModel because it should know how to validate itself
Should i create an attribute which validates the property which i place on the ViewModels property
Should i place it in a Vacancy[thisviewmodelsname]Validator where i put all validation logic for this specific viewmodel
Any ideas appreciated....
We already have the simple validation in place: these are attributes
on the viewmodel, like [required], [numeric] , [email] etc. (this is
open for discussion too, btw)
I would recommend FluentValidation.NET instead of Data Annotations which plays nicely with ASP.NET MVC. It provides a nice syntax for expressing complex validation logic between interdependent properties without writing millions of lines of plumbing infrastructure code (which is what you would have to do if you use Data Annotations and write a custom validator) and also allows you to unit test your validation logic very easily.
Because if it is not a valid countryid, my datalayer generates an error.
There you go - your data layer already handles this validation for you. But if you don't want to leave it to reach the data layer then you could have a validation rule for this property on the view model. If you follow my previous advice about FluentValidation.NET you will already know where to put this rule - in the corresponding validator of your view model.
You put your validation obviously to the view model. This way it is located in one spot (not scattered, hence DRY) and operational on both client and server.
For simple scenarios use Data Annotations.
For more sophisticated scenarios (enterprise scale etc) use Fluent Validation
Hope this helps.
The best way is to combine client and server validation. For client side validation you can use jquery validation plugin. It provides all standart validation patterns(like maxlength, minlength, required etc.).You can specify validation requirements in model attributes(data annotation) or directly in html. Also, it provides possibility for custom remote validation when validation result will be returned from server code.
But you should dublicate client side validation with server side. For example, use spring.net validation . I think it's the best generic and flexible framework.
I want to be able to perform validation from within my Service classes. I have a Controller action that looks something like this:
public ActionResult Edit(Post post)
{
if(!ModelState.IsValid)
return View();
_postDataService.SavePost(post);
return View("Index");
}
I don't like the fact that my _postDataService.SavePost() can save invalid data and I want to move the model validation to my _postDataService.SavePost() method. My question is what is the most elegant way to do this? And if I move my model validation to my Service method, how do I return my model errors back to my controller? Lastly, where would model validation like uniqueness of the email address go since it require's some data access? Of all the similar questions i've looked at, none of them give a straight forward way to do this.
I also considered this solution but this article is old and I have a feeling it's not up-to-date.
I assume you are doing validation by putting attributes on properties in your Post model/entity class. If so, you can validate in your service layer by doing this:
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(post,
new ValidationContext(post, null, null), results, true);
This is essentially what the default modelbinder does when it validates and configures the ModelState object for the controller / action.
The beauty of this approach is that you don't have to return validation errors from the service layer. You will just rely on the default modelbinder to do the above code automatically. If someone ever tries to invoke that action without checking ModelState.IsValid, just have your service method throw an exception to remind them.
Update after comment
Yes, my answer recommends doing the validation twice.
How do I feel about it? I don't mind. We use Entity Framework 4.1 with MVC, and do not use entities in MVC. Instead we use automapper to DTO the entities into a separate viewmodel layer. Our EF entities are also decorated with ValidationAttributes, which EF evaluates automatically during any DbContext.SaveChanges() operation. We apply very similar validation attributes on properties of our viewmodel classes. This might not seem DRY, and there is definitely overlap, but in some cases the validation attributes on the UI side can be different than the validation attributes in the domain model.
We do not do validation in a service layer. Our service layer is simply an application flow coordinator, and takes no responsibility for business rules. However, validation still happens twice in our application. First, by the default model binder, against the viewmodel validation rules. Then if the transaction makes it to EF, validation performed against the entities. So we are actually validating 2 separate layers.
If you think about it though, you really are tackling 2 different concerns here. In the UI, you want MVC to display validation messages to users. ModelState is great for this, since it hooks nicely with MVC validation (model binding / jquery / unobtrusive / client-validation / etc).
Conversely in the domain, you are protecting your data integrity and enforcing business rules. The domain doesn't care about displaying messages to a user. For all it knows, the client may be a machine, WCF service, or something else. The role of the domain is to prevent a transaction from occurring, and (in our case) throws an exception rather than quietly trying to "work with" the client.
At the start of the development I faced with problem called "an impedance mismatch between domain model and the view". To solve this problem I decide to use ViewModel pattern - for every view (that is strongly typed) we create viewmodel class. But where is the validation logic is locate - in viewmodel classes or in our domain model objects? And where we need to perform operations to query database - in controller action, and then populate viewmodel or straight in viewmodel?
Thank you.
You should have validation logic for the viewmodel. This is what the view sends and what should be validated. As far as populating the viewmodel is concerned here's how to proceed: write a repository which queries the database and returns models. Then map those models to viewmodels (AutoMapper can help you here). Finally return viewmodels to the view. This also works the other way around: the users POSTs some data to a controller action as the form of a viewmodel which once validated is mapped back to a model and passed to the repository for update.
As an alternative to Data Annotations you may take a look at FluentValidation for validating your view models. It integrates nicely with ASP.NET MVC.
Im trying to choose the best server/client validation framework to use with my MVC application. I would like to know what is the best validation framework to use with MVC to do server/client validation.
My options are:
Castle validator
Microsoft Data Annotations
nHibernate Validator
With the upcoming MVC 2, it looks like MS is leaning towards the System.ComponentModel.DataAnnotations library. It's pretty nice - does a lot of code generation for you.
I've been using xVal with great success.
The best thing is you can fully automate validation:
put DataAnnotations (or special rules) to your business layer POCO classes (if you have them) or entity classes' metadata buddy classes if you use entities up to controller layer
write an ActionFilter that will automatically validate parameters to your controller actions - it's best if all your POCOs (or entities) implement a certain interface that defines Validate() method, filter calls this method and fills ModelState.Errors when validation fails.
Add if (ModelState.IsValid) { ... } in your controller action that needs to work differently when model isn't valid
Put <%= Html.ValidationMessage(...) %> in your views that will display validation errors
Add xVal's client validation to your views if desired
This way you've set up automatic object validation. All your controller actions will do is check Model validity.
Asp.net MVC 2 will have something very similar to xVal already built in the framework so it's up to you which version are you using.