asp.net-mvcmodelmetadatametadatatype

Is there a way to instruct ASP.NET MVC about some class metadata other than putting the MetadataTypeAttribute directly on the class?


Here's a sample of how it works now:

[MetadataType(typeof(PersonMetadata))]
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class PersonMetadata
{
    [Required]
    public string Name { get; set; }
    [Range(0,150]
    public int Age { get; set; }
}

However I don't want the MetadataAttribute to be put on the Person class, instead I want some way of telling the MVC framework "hey if you encounter Person class the metadate is in the PersonMetadata class".

It's just reversing the direction which for me feels more compositional and following the Open-Close Principle since I don't have to touch the Person class to "extend" it with metadata.
I know this creates a problem of possible multiple and conflicting metadatas being attached, also increases complexity but flexibility always comes at a price.

I want either a programmatic or declarative way or preferably both :)

So one could be something like :

MetadataTypeMappings.Add(typeof(Person), typeof(PersonMetadata));

Another could be:

[MetadataFor(typeof(Person)]
public class PersonMetadata
{
    [Required]
    public string Name { get; set; }
    [Range(0,150]
    public int Age { get; set; }
}

Solution

  • I'm using MvcExtensions. One of the features is a nice way to describe metadata like this:

    public class ProductEditModelConfiguration : 
      ModelMetadataConfiguration<ProductEditModel>
    {
      public ProductEditModelConfiguration()
      {
        Configure(model => model.Id).Hide();
        Configure(model => model.Name)
          .DisplayName(() => LocalizedTexts.Name)
          .Required(() => LocalizedTexts.NameCannotBeBlank)
          .MaximumLength(64, () => 
            LocalizedTexts.NameCannotBeMoreThanSixtyFourCharacters);
      }
    }
    

    Neat thing is - this allows to use resources for localization in strongly typed fashion.

    Drawback for using this - there's bunch of other things bundled which You might not want to use.