views:

28

answers:

1

Hi,

I'm working on an ASP.NET MVC 2 project with some business entities that have metadata dataannotations attributes applied to them (Validation attributes, Display attributes, etc.).

Something like:

//User entity
public class User
{

            [DisplayName("Vorname")]
            [Required(ErrorMessage = "Vorname fehlt")]
            [StringLength(MaxNameLength, ErrorMessage = "Vorname ist zu lang")]
            public string FirstName { get; set; }

            [DisplayName("Nachname")]
            [Required(ErrorMessage = "Nachnamefehlt")]
            [StringLength(MaxNameLength, ErrorMessage = "Nachname ist zu lang")]
            public string LastName { get; set; }

            [Required]
            public string Password{ get; set; }
}

Using the metadata from different views is no problem, as long as I am using my business entities as viewmodels or as part of a viewmodel like this:

//custom viewmodel with a user entity
public class CustomViewModel
{
   public User{get;set;}
   //some more properties...
}

However, sometimes I need to code a view for editing some, but not all fields of an entity. For those fields I want to reuse the metadata already specified in my user entity. The other fields should be ignored. I'm talking about custom view models like this:

[MetadataType(typeof(User))]
public class UserNameViewModel
    {

                public string FirstName { get; set; }

                public string LastName { get; set; }

                //no password on purpose, the user should only 
                //edit his first and last name in this view
    }

That's where I am running into problems. The custom view model above leads to an exception when the view is generated, because it has no password property.

The associated metadata type for type 'Zeiterfassung.Models.ViewModels.Users.UserNameViewModel+UserModel' contains the following unknown properties or fields: Password. Please make sure that the names of these members match the names of the properties on the main type.

Also, even if this exception did not occur, I expect to get into even more trouble with model validation on form submit because Password is marked as required in my business entity.

I can think of several workarounds, but none seem really ideal. In any case I can't change the database layout so that the password field would be in a separate entity in my example above.

How would you handle this scenario?

A: 

The only recommendation I could give you is to have view models specific to each view and have only the necessary properties and validation attributes on those view models. Don't worry if you repeat some validation attributes and properties on your view models. That's what they are meant for: reflect the logic of a given view.

Darin Dimitrov
That's what I have been doing so far, but it's a lot of duplicate code (in the form of metadata attributes). It also means having to unit test validation attributes for several models instead of just one model, even though in essence I only have the same validation rules on all models (for example, FirstName should always be required).
Adrian Grigore
Darin Dimitrov
It's not a huge problem, but it's a lot of extra work, mostly in the form of extra unit tests. It also means a higher potential for bugs because when validation rules change on my business model, I will have to update several view model rules as well. It's easy to forget one of those in the process.
Adrian Grigore