ModelMetadata Fluent Configuration

hazzik edited this page Apr 14, 2012 · 9 revisions

MvcExtensions has an excellent replacement for DataAnnotations model metadata configurations: fluent model metadata configurations. It is provided unlimited flexibility and extensiblity for you metadata.

First of all you need to enable registration of all you metadata. For that include RegisterModelMetadata task into bootstrapper execution sequence:

public class MvcApplication : WindsorMvcApplication
{
    public MvcApplication()
    {
        Bootstrapper.BootstrapperTasks
            .Include<RegisterRoutes>()
            .Include<RegisterControllers>()
            .Include<RegisterModelMetadata>();
    }
}

Second write some metadata configurations:

public class ChangePasswordMetadata : MvcExtensions.ModelMetadataConfiguration<ChangePassword>
{
    public ChangePasswordMetadata()
    {
        Configure(x => x.OldPassword)
            .DisplayName("Old password")
            .Required("Old password is required")
            .AsPassword();

        Configure(x => x.NewPassword)
            .DisplayName("New password")
            .Required("New password is required")
            .MinimumLength(6, "Password length should be at least 6 characters")
            .AsPassword();

        Configure(x => x.ConfirmPassword)
            .DisplayName("Password confirmation")
            .Required("Password confirmation is required")
            .Compare("NewPassword", "Password and its confirmation should be equal")
            .AsPassword();
    }
}

Localization with ModelMetadata

MvcExtensions provides a flexible way to perform localization for your models and validation messages. You can use the resource files in following way:

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);

        Configure(model => model.Category).DisplayName(() => LocalizedTexts.Category)
            .Required(() => LocalizedTexts.CategoryMustBeSelected)
            .AsDropDownList("categories", () => LocalizedTexts.SelectCategory);

        Configure(model => model.Price).DisplayName(() => LocalizedTexts.Price)
            .FormatAsCurrency()
            .Required(() => LocalizedTexts.PriceCannotBeBlank)
            .Range(10.00m, 1000.00m, () => LocalizedTexts.PriceMustBeBetweenTenToThousand);
    }
}

As you can see we are using Func<string> to set the localized text, this is just an overload with the regular string method.

Read more about localization http://weblogs.asp.net/rashid/archive/2010/06/14/localization-with-asp-net-mvc-modelmetadata.aspx