I have a custom DataAnnotationsModelMetadataProvider
and I'd like to return an object derived from ModelMetadata
so that I can have extra properties in my razor templates.
So far my custom provider only overrides the CreateMetadata
function:
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
ModelMetadataAttribute mma;
foreach (Attribute a in attributes)
{
mma = a as ModelMetadataAttribute;
if (mma != null)
mma.Process(modelMetadata);
}
return modelMetadata;
}
so that every attribute derived from ModelMetadataAttribute
can do some custom actions (actually it only adds AdditionalValues
)
But since nearly all of my attributes mainly add attributes to the html elements I generate in my razor template, I'd like the ModelMetadata
in the view to contain a dictionnary of the attributes I want to add (and some other things).
So I need a class that inherits from DataAnnotationsModelMetadata
.
I can't just call the base.CreateMetadata
function since it won't cast properly to my derived class.
I thought about making a copy of public properties of DataAnnotationsModelMetadata
returned by the base.CreateMetadata
function into my derived class, but I can loose information so it doesn't seem safe.
Another way I thought of is to copy/paste the base code of CreateMetadata
and add my logic, but it seems ugly... (and I only have the mvc3 sources, so it might have changed in mvc4)
Also thought of inheriting from ViewDataDictionnary
so that I can provide my custom metadata class instead of the standard one, but I don't have a clue about how to do this. (also I admit I didn't dig much on that particular question)
I looked at a lot of articles about DataAnnotations
and providers but couldn't find something similar to what I'm trying to do.
So what are my options here? In which direction could I search to get closer to what I want to do?
EDIT:
I looked at this question (quite similar): Can I achieve a 'copy constructor' in C# that copies from a derived class?
but what it does is a copy of properties and I wanted to avoid that.
In the last answer in this post there's something about PopulateMetadata
but I can't find that function in the base provider...
After some thinking, I actually found a solution that doesn't need to use
MvcExtensions
and that copies all the information contained in the base class to the derived one.Since
DataAnnotationsModelMetadata
and its base classes don't do anything but initialize some private or protected values, there is no risk of having side effects to do that.And if you want a generic solution to get base class fields in your derived one, and you can't just use inheritance because you're in the same kind of situation I was, just use this class:
I suggest you to take a look at
MvcExtensions
: http://mvcextensions.github.io/One of it's main part is exactly what you are doing - extensive model metadata configuration/ usage. You may find a lot of answers there or simply take it as a "ready to use" solution.