Say we have the following (overly simple) scenario:
We have a screen to view person details and a screen to edit person details.
The screen display person details has the following fields (as display only):
First Name Last Name Bio
The screen edit person details shows has following fields (in input controls):
ID (hidden) First Name Last Name Bio
Say our display viewmodel looks like this:
public class DisplayPersonViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Bio { get; set; }
}
And our edit viewmodel looks like this:
public class EditPersonViewModel
{
[Required]
public int ID { get; set; }
[Required]
[StringLength(20)]
public string FirstName { get; set; }
[Required]
[StringLength(20)]
public string LastName { get; set; }
[Required]
public string Bio { get; set; }
}
Not much difference between the 2, eh? The edit model has one extra field (ID) and some of attributes on the properties. Now, if we were to combine the 2 like this:
public class DisplayPersonViewModel
{
[Required]
[StringLength(20)]
public string FirstName { get; set; }
[Required]
[StringLength(20)]
public string LastName { get; set; }
[Required]
public string Bio { get; set; }
}
public class EditPersonViewModel : DisplayPersonViewModel
{
[Required]
public int ID { get; set; }
}
This is certainly more DRY, since we don't have duplicate fields to maintain, but now we have extraneous info (attributes) on our display viewmodel. I'm leaning more towards the second approach, regardless, because some of our screens have over 25 fields! (...and that's out of my control, so please don't harp on it :) ...) However, I just want to hear opinions to get a better sense of what may be "best practice".
Yes, the second approach seems fine to me. No worries other than this itchy feeling in your stomach telling you why on earth are you decorating a display view model with validation attributes. But if you can live with it it's really something that is preferred compared to duplicating the view models.
Unfortunately personally I cannot live with this feeling in my stomach and that's why I use FluentValidation.NET to define my validation rules instead of data annotations. It allows me to have those rules separately from my view models and then I don't worry about polluting the so called display view model with validation rules. So I would define in the same way as you 2 view models and
EditPersonViewModel
would derive fromDisplayPersonViewModel
and then define myEditPersonViewModelValidator
for theEditPersonViewModel
in a separate class.Oh and a side note: decorating a non-nullable type with the
[Required]
attribute is not necessary. All non-nullable types are required by their very basic nature. So instead of:you should only have:
Another option is to use the MetadataType Attribute.
Your raw Person model is attribute free. Your Display and Edit models only have the attributes you actually need for the View.