ASP.NET MVC 2 validation using DTOs instead of domain entities - asp.net-mvc

I'm struggling to mesh two best practices together:
Using DataAnnotations + ModelBinding for validation in ASP.NET MVC 2
Using DTOs instead of domain entities when passing data via the ViewModel
If I want to pass over DTOs instead of domain entities, then leveraging DataAnnotations + ModelBinding for validation would require me to specify validation attributes on my DTO classes. This results in a lot of duplicated work since multiple DTOs may hold overlapping fields with the same validation restrictions. This means that any time I change a validation rule in my domain, I have to go find all DTOs that correspond with that value and update their validation attributes.

You shouldn't have more than one DTO per entity, so you should only have to apply the validation attributes once per DTO. If you need multiple entities for a View, include multiple DTO's as properties of your ViewModel.

You might find useful this.
And keep in mind that validation lives everywhere. There is nothing wrong if DTOs applies UI validation (like getting necessary fields filled, datetime in correct format etc.) and domain objects - domain validation (e.g. account has money before withdrawn operation).
You can't create validation universal. Best thing You can do - put it in appropriate places.
And weed that feeling about duplication out. Usage of DTOs usually means applying single responsibility principle. There is no duplication if you got 2 customer objects where one is responsible for carrying business logic and second that is responsible for displaying it.

Maybe you could use meta annotations, which puts the attributes on a separate class:
namespace MvcApplication1.Models
{
[MetadataType(typeof(MovieMetaData))]
public partial class Movie
{
}
public class MovieMetaData
{
[Required]
public object Title { get; set; }
[Required]
[StringLength(5)]
public object Director { get; set; }
[DisplayName("Date Released")]
[Required]
public object DateReleased { get; set; }
}
}
Code sample was borrowed from this article.

Related

Serverside validation framework for the models(using data annotations) in asp.net mvc

I have so many classes in Models used as entities for my application.
I'm using data annotations for the model attributes as below:
[Required]
[DataMember]
public string UserName { get; set; }
I do not want to use data annotation for each n every model.
I want to have a generic validation framework which will have a method that can be used to validate all the properties in my model class.
Has anyone used such a generic type of validation to do server side validations, please help?
Thank you

Benefits of not passing entities to view

I usually see people telling that you should not pass entities to your View. They say you should use a DTO/VO/ViewModel/AnyOtherThingYouWant instead, as using an entity would increase the coupling.
Ignoring the moments where I do need some extra logic (or I don't need all the properties), I fail to see any benefits in doing this. For example, consider the following class:
public class Contact {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
I see lots of code that creates another class, like this:
public class ContactDTO {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
use it in the View and then do this:
someMapper.Map(contactDto).To<Contact>();
I can't see how better this is than simply using the Contact class, as your View would be coupled to a class that is coupled to the entity's class. So, every change in one should be replicated into the other. From my point of view, the 'middle' object is there just to add complexity, but not real value.
I know that there's no 'one size fits all' solution (as sometimes, using the middle object would make sense), but do we really need adding code like this? What are the real benefits?
Think of it this way: a view is a projection of your domain. It's a specific representation of your business model. So you need to use a view model which will represent this projection. It could be a subset of the domain model but it could also be an aggregation of multiple domain models if the view requires it. The example you provided is just a specific case where there is a 1:1 mapping between the domain model and the view model because of the requirements of this specific view. But that's only one specific view. I suppose that your application has many views and different representations of your domain entities.
There are many view specific things that make your domain models unsuitable and thus the need of view models. For example validation. A given domain model property could be required in some view and not required on another view (think of Id property in Create/Update views). If you don't use a view model but have your Create controller action directly take the domain model you will have a problem if your domain model Id property is decorated with the Required attribute.
There are many other examples. If I had one advice to give you when developing an ASP.NET MVC application it would be this: always define specific view models for your views and never pass/take domain models to/from views and this stands true even in cases where you have a 1:1 mapping between your domain model and the view model.
The cited approach is a kind of purism. If you do not need to transform (reduce, merge, whatever) your domain objects and they are directly usable in your view as they are, use them - you can introduce DTO via refactoring later, when necessary.
So you have to take into consideration what Darin Dimitrov said but keep in mind that DTOs and similar are here to make your work easier. I recall one project I worked on - more than 90% of DTOs were ono-to-one copies of the domain objects - this is totally useless and only adds to the maintenance cost.

How to avoid needing a VIewModel for every Model

I'm using ASP.NET 4 and MVC3.
Often, I find that I need a ViewModel to display information for my Model. For example, take the following model
class Profile
{
public int UserID { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
There is a requirement to hide the UserID, but to show the UserName, so often time for models that are similar to the one above, I have to come up with a ViewModel with just the UserID changed to UserName:
class ProfileViewModel
{
public string UserName { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
Are there any ways?
Until recently I always passed my models to my action methods as I also thought that creating viewModels with the same property names was duplication (its not). This caused me a lot of pain. I have now been re-educated and almost always use viewModels exclusively in my action methods (of course there will always be situations were it is fine to pass the model directly to the action method).
Have a read of this post which is the one that converted me to using viewModels. This will tell you the following:
The difference between models and viewModels
When each should be used.
How to avoid some security issues with the default model binder.
On top of the information in the linked post you should also consider things such as validation. I had a model that implemented the IValidateableObject interface to ensure the entity was in a valid state before being saved to the database.
In my ASP.NET application I wanted to create a multi-step form that allowed the user to enter the information over a number of pages. The problem I had here was that ASP.NET also uses the IValidatableObject interface during the model binding process.
If you are only allowing the user to enter a subset of the information required for the entity, the model binder will only be able to fill in the information that was given. Depending on how complex your validation is, this can result in the ModelState being marked as invalid as the entire entity is not valid.
The way I got around this was to have a viewModel representing each step each with its own validation. This way you are only validating the properties at each step. Once you get to the final step and everything is valid, I create an appropriate entity using the information given by the user. This entity will only have database-level validation checks performed upon it (field lengths etc.)
My suggestion is not to avoid viewModels but to understand why they are used and embrace them.
No, there isn't, once a member is public, it's public. Now, if the UserID property was internal, then you wouldn't have that problem.
However, one of the aims of MVVM here is to encapsulate logic regarding the interaction of the model and the view. Even if you have the view model and model in separate assemblies and make the UserID property internal, you should still have a view model; if changes come down the line where more functionality is required than simply binding to the model, you are prepared.
Direct access to the model is always a no no.
Additionally, if you really wanted, you could always use T4 templates to auto-generate the code for you (you could use Code DOM on the original CS file) to output your view models for you.
I usually have multiple ViewModels per model - the tradeoff you have to make comes down to this:
Are you comfortable coupling business logic (data annotations, display information, etc...) with your (persistence) models?
Are you comfortable doing all of the hide / display business logic purely within the View and not use the Controller + scaffolding to make those decisions for you?
The downside of creating all of those ViewModels of course is sub-class explosion, but the right way to think about it is in terms of the questions I listed IMHO.

Using EF POCO classes as MVC 2 models (with data annotations)

I have a 4 layered web application programmed in C#... .Net 4.0:
UI Layer
Business Layer
Data access Layer
Entities layer
My data layer contains an edmx
My entities layer contains my POCO objects (generated by a t4 script), and that layer is referenced in all other layers.
When creating an MVC form to create a new customer, for example.... I already have the customer class with fields for first name, last name, etc in my entities layer, but that auto-generated POCO class does not have data annotations for validation... I.E. [Required], etc. for when the form is submitted
My solution right now is to create new model classes that are pretty much the same as my poco classes but also have these additional validation annotations.
What I want to know is if theres an easy way to use certain POCO objects in the MVC model (in the UI layer) without having to almost rewrite the class... and also without modifying the t4 that generates these POCO classes (since I'm not up to speed on t4).
I saw this from another post on stackoverflow http://automapper.codeplex.com/ ... not sure if this will do it or is the best solution.
If your POCO class is declared as such:
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
}
then if you just change the T4 to make it a partial class, you can then define in a separate file:
[MetadataType(typeof(PersonMetadata))]
public partial class Person {
internal class PersonMetadata {
[Required]
// insert other metadata here
public string FirstName { get; set; }
// and if you don't want metadata for lastname, you can leave it out
}
}
Two extra points - the metadata class doesn't have to be nested in the partial you define, I think it's neater though. Also, the types don't have to match in the metadata class, so you could make them all object if you wanted to (and you might see some examples on the web with it like this)
Modifying a T4 template is not very hard at all. I recently faced the same issue and decided to read up on T4 a bit and then modify the template to create the generated properties the way I need them (annotations, and in my case with NotifyPropertyChange etc. as I use the same POCO objects in an MVC UI and in a Silverlight UI).
Even though you're looking for a solution that doesn't require modifying T4, I hope this is useful.

DRY Validation with MVC2

I'm trying to figure out how I can define validation rules for my domain objects in one single location within my application but have run in to a snag...
Some background: My application has several parts:
- Database
- DAL
- Business Logic Layer
- SOAP API Layer
- MVC website
The MVC website accesses the database via the SOAP API, just as third parties would. We are using server and and client side validation on the MVC website as well as in the SOAP API Layer.
To avoid having to manually write client side validation we are implementing strongly typed views in conjunction with the Html.TextBoxFor and Html.ValidationMessageFor HTML helpers, as shown in Step 3 here. We also create custom models for each form where one form takes input for multiple domain objects.
This is where the problem begins, the HTML helpers read from the model for the data annotation validation attributes. In most cases our forms deal with multiple domain objects and you can't specify more than one type in the <%#Page ... Inherits="System.Web.Mvc.ViewPage<MvcApplication.Models.SomeModel>" %> page directive. So we are forced to create a custom model class, which would mean duplicating validation attributes from the domain objects on to the model class.
I've spent quite some time looking for workarounds to this, such has referencing the same MetadataType from both the domain class and the custom MVC models, but that won't work for several reasons:
You can only specify one MetadataType attribute per class, so its a problem if a model references multiple domain objects, each with their own metadata type.
The data annotation validation code throws an exception if the model class doesn't contain a property that is specified in the referenced MetadataType which is a problem with the model only deals with a subset of the properties for a given domain object.
I've looked at other solutions as well but to no avail. If anyone has any ideas on how to achieve a single source for validation logic that would work across MVC client and server side validation functionality and other locations (such as my SOAP API) I would love to hear it!
Thanks in advance,
Matthew
What you should do is instead of trying to replicate the structure in the view models, use your existing models in the data model classes.
When you bind the form data back to the view model, you can restrict which columns will be bound back using the [Bind] attribute on the parameter. Or use any other approaches to do this.
So if your model creates classes like Product User and Category, and your view model needs to use some of their properties, create a view model like this:
public class PageViewModel
{
public Product Product { get; set; }
public Category Category { get; set; }
public User User { get; set; }
}
In your page you will be able to use them with
<%: Html.EditorFor(m => m.Product.ProductName) %>
In this case the validation attributes from your actual classes will be used, as required.
Does that give you an acceptable solution?
How about returning a container class that has nested types in your action method?
http://weblogs.asp.net/blogs/rajbk/image_63B7D5D4.png

Resources