asp.net mvc add model meta data without attributes

2019-05-22 14:06发布

问题:

In our asp.net mvc forms we will typically add attributes to our view model properties such as DisplayName, Description and Required.

We'll then just call Html.EditorFor(model => model.PropertyName) for each property.

I now have a situation where I don't have a strongly typed viewmodel to which I can apply such attributes. Instead I have a list of the following class:

public class AttributeValue
{
    public string Name { get; set; }
    public string Description { get; set; }
    public bool Required { get;set; }
    public object AttributeValue { get; set; }
}

How can I add the meta data manually using the information stored in the above class, so that the EditorFor helper and validation still works?

回答1:

You should write custom ModelMetadataProvider and ModelValidatorProvider classes

public class DynamicModelValidatorProvider : ModelValidatorProvider
{
    public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
    {
        // you validation logic go there
        yield break;
    }
}


public class DynamicModelMetadataProvider : ModelMetadataProvider
{
    public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType)
    {
        yield return new ModelMetadata(this, containerType, null, typeof (string), "Hello");
        yield return new ModelMetadata(this, containerType, null, typeof (string), "World");
    }

    public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
    {
        return GetMetadataForProperties(null, containerType).SingleOrDefault(x => x.PropertyName == propertyName);
    }

    public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType)
    {
        return new ModelMetadata(this, null, modelAccessor, modelType, null);
    }
}


回答2:

I think your going to be much better off writing a custom object template.

Please check out Brad Wilson's series on how to work with templates in ASP.NET MVC, which you can find here:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

From there, you will find the default object templates for both display and edit.

You will need to modify the template so that, instead of getting the values form meta data, you get them from the model.