2

I am writing a custom ModelMetadataProvider which extends default DataAnnotationsModelMetadataProvider. Unfortunately i came across an issue: ModelMetadata.Container property is always null. According to msdn description of ModelMetadata Class, container property should not be null when model represents a property:

enter image description here

But when overriding GetMetadataForProperty method, after calling base implementation Container property always returns as null:

enter image description here

protected override ModelMetadata GetMetadataForProperty(
            Func<object> modelAccessor, 
            Type containerType, 
            PropertyDescriptor propertyDescriptor)
        {
            ModelMetadata metadata = base.GetMetadataForProperty(modelAccessor, containerType, propertyDescriptor); 

            // metadata.Container always null here                
        }

On the other way, when accessing ModelMetadata from ViewData, Container property gets filled as expected:

enter image description here

Thus I have couple of questions related to this issue:

  1. Is it an expected behavior that ModelMetadata.Container returns empty from GetMetadataForProperty or it is a bug?

  2. Is there a way to get ModelMetadata.Container property filled inside ModelMetadataProvider?

  3. When ModelMetadata.Container property actually gets it's content?

Aaron Hudon
  • 5,280
  • 4
  • 53
  • 60
Alex Art.
  • 8,711
  • 3
  • 29
  • 47

1 Answers1

3

Metadata is created from the innermost properties out, so the container model's metadata has not yet been created at the time GetMetadataForProperty is called (the same applies for OnMetadataCreated when you implement IMetadatAware). The reason you can acess it from ViewData is that the process of creating all metadata has been completed.

  • First of all thank you for the answer but I noticed a following behavior that slightly contradicts with it: each time that I hit Html.EditorFor in the view i see that it calls for GetMetadataForProperty. ViewData.ModelMetadta.Container is available prior to this call so how come it is not available in inside GetMetadataForProperty that is called after? – Alex Art. Jan 17 '15 at 12:17
  • 1
    Interesting. Some time ago I was trying to work out the same problem your having and created a model containing a value type and a complex object, which in turn contained a value type and a complex objects (3 levels deep) and debugged it, which showed that the metadata was being created from the inner properties out. Time for some more tests :) –  Jan 17 '15 at 12:27
  • @StephenMuecke any resolution on this? Having reference to the container type would be quite helpful – Aaron Hudon Feb 13 '18 at 20:59
  • 1
    @AaronHudon, I remember doing a few tests on this at the time, but it was a year ago and I cannot remember now what the outcome was. I'll try and find some time next week to follow it up again. –  Feb 17 '18 at 07:41