Dive Deep Into MVC: ModelMetadata and ModelMetadataProvider

What is the ModelMetadata?

The ModelMetadata introduced in ASP.NET MVC 2 that holds the metadata for a model. Assume we have a model called Book; without doubt it has some properties such as name, price and author. Something as follows.

public class Book
{
    public string Name { get; set; }
    public int Price { get; set; }
    public Author Author { get; set; }
}

ModelMetadata Members

Properties

You can get the set of properties metadata by using Properties. This property uses GetMetadataForProperties that is a method of ModelMetadataProvider class.

Node: There are some differences between a property metadata and a model metadata.

PropertyName and ContainerType

If the metadata is about a property, the PropertyName indicates its name. Also the ContainerType indicates the type of its owner. Otherwise, these properties are null.

IsReadOnly

As you know, the property can be read-only due to the lack of setter method. You can make a property read-only through ReadOnlyAttribute as well. The IsReadOnly property indicates whether the property is read-only or not.

IsRequired and IsNullableValueType

As you know, the value types do not support null. The Nullable introduced in C# 2 that resolved the problem. Therefore the value type properties that are not nullable are required by default. By using IsNullableValueType you can indicate whether the property is a nullable value type or not. The RequiredAttribute is another reason that the property is required. Anyway, the IsRequired property indicates whether the property is required or not.

IsComplex

Each type that is not convertible to/from string is complex. You can sense whether the property is complex through IsComplex property.

DisplayName

The name of model that will be shown as a label. Use DisplayNameAttribute to set it.

DisplayFormatString, EditFormatString, NullDisplayText and ConvertEmptyStringToNull

To format the model, use DisplayFormatAttribute.

DisplayFormatAttribute properties

ApplyFormatInEditMode

The display format string won't be assigned during editable view unless the ApplyFormatInEditMode is true.

NullDisplayText

To show a text while the model is null, use NullDisplayText property.

ConvertEmptyStringToNull

To disable the empty string to null conversion for the model, set ConvertEmptyStringToNull to false.

ShowForEdit, ShowForDisplay and HideSurroundingHtml

Sometimes you need to exempt some properties from view and edit or even you are after to render the property as a Hidden Input, use ScaffoldColumnAttribute or HiddenInputAttribute in these cases. These properties indicate the status of above attributes.

GetValidators

Returns the set of associated validators for the model.

GetDisplayName

If you are after to the model's display name, you have to use GetDisplayName method. It attempts to return the value of DisplayName property. But it can be null which returns the PropertyName in this case. Lastly, if all of these properties are null, returns the model's type name.

That was a small hint to the ModelMetadata. You can learn more about ModelMetadata and related attributes from Brad Wilson.

What is the ModelMetadataProvider?

In general, the ModelMetadataProvider is an abstract base class for all of providers. A metadata provider produces a ModelMetadata for the model.

public abstract class ModelMetadataProvider
{
    public abstract IEnumerable GetMetadataForProperties(object container, Type containerType);
    public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
    public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
}

The above code demonstrated the ModelMetadataProvider structure.

ModelMetadataProvider Members

GetMetadataForType

Its summary has said "Gets ModelMetadata for the specified model accessor and model type". It has two parameters. The modelAccessor parameter is a parameterless delegate that returns an object. Sometimes holds a method that can return the model. The second parameter specifies the type of model.

GetMetadataForProperty

Its summary has said "Gets ModelMetadata for the specified property". The first parameter is already introduced above. The second parameter demonstrates the container type. And the last specifies the name of property.

GetMetadataForProperties

Its summary has said "Gets a ModelMetadata for each property of a model". The first parameter gives container itself. And the last gives the type of container.

What is the AssociatedMetadataProvider?

The AssociatedMetadataProvider is an abstract class derived from ModelMetadataProvider and provides a new base class for providers. It has only an abstract method instead of three called CreateMetadata. By the way, you can access to the set of model's attributes without reflection via attribute parameter. Other parameters are the same as above.

public abstract class AssociatedMetadataProvider : ModelMetadataProvider
{
    protected abstract ModelMetadata CreateMetadata(IEnumerable attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
}

What is the ModelMetadataProviders?

Frankly, the ModelMetadataProviders is a static class that holds an instance of current ModelMetadataProvider. The Current property returns DataAnnotationsModelMetadataProvider by default.

Download Example

In example I demonstrated how to create a custom ModelMetadataProvider that extracts the metadata from an XML file. The completed source code is available here...

blog comments powered by Disqus