How can I extend CachedDataAnnotationsModelMetadat

2019-05-05 23:20发布

问题:

We are looking to use CachedDataAnnotationsModelMetadataProvider as it improves performance and we use a lot of Meta Data in our MVC4 application.

We are currently creating a custom ModelMetadataProvider inheriting from DataAnnotationsModelMetadataProvider and overriding CreateMetadata attribute to do some automatic display name creation e.g. remove Id from names etc. However we also want to cache it so we wanted to base our custom ModelMetadataProvider on CachedDataAnnotationsModelMetadataProvider.

If we try to override CreateMetadata we can't as it is sealed. Any reason it is sealed - I guess I can get the source and just reimplement just found it odd that I couldn't extended?

Has anyone done anything similar?

回答1:

I would guess that the reason it is sealed is because the actual CreateMetadata implementation contains caching logic that you should not be modifying.

To extend CachedDataAnnotationsModelMetadataProvider, I find that the following seems to work well:

 using System.Web.Mvc;

 public class MyCustomMetadataProvider : CachedDataAnnotationsModelMetadataProvider
 {
      protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
      {
           var result = base.CreateMetadataFromPrototype(prototype, modelAccessor);

           //modify the base result with your custom logic, typically adding items from
           //prototype.AdditionalValues, e.g.
           result.AdditionalValues.Add("MyCustomValuesKey", prototype.AdditionalValues["MyCustomValuesKey"]);

           return result;
      }

      protected override CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable<Attribute> attributes, Type containerType, Type modelType, string propertyName)
      {
           CachedDataAnnotationsModelMetadata prototype = base.CreateMetadataPrototype(attributes, containerType, modelType, propertyName);

           //Add custom prototype data, e.g.
           prototype.AdditionalValues.Add("MyCustomValuesKey", "MyCustomValuesData");

           return prototype;
      }
 }