从MetadataProviders开始,我很想探索框架的扩展点.我目前已经成功实现了填充ModelMetadata.IsRequired属性RequiredAttribute,但我似乎无法找到覆盖之间的区别,CreateMetadata()或者GetMetadataForProperty()因为两个选项似乎都有效.
一般来说,我见过的例子都覆盖了CreateMetadata().
作为额外的:是否有任何好的资源(博客,书籍)可以从这个扩展点学习?
该GetMetadataForProperty()声明的类ModelMetadataProvider.
AssociatedMetadataProvider来源于ModelMetadataProvider. CreateMetadata()被宣布AssociatedMetadataProvider.该DataAnnotationsMetadataProvider是你提供源自链接重写AssociatedMetadataProvider.
MVC框架使得以调用ModelMetadataProvider的GetMetadataForProperty()方法.
覆盖的原因CreateMetadata()是因为你AssociatedModelMetadataProvider的默认实现GetMetadataForProperty()调用了CreateMetadata().它看起来像这样:
public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
{
if (containerType == null)
{
throw new ArgumentNullException("containerType");
}
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "propertyName");
}
PropertyDescriptor propertyDescriptor = this.GetTypeDescriptor(containerType).GetProperties().Find(propertyName, true);
if (propertyDescriptor == null)
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MvcResources.Common_PropertyNotFound, new object[] { containerType.FullName, propertyName }));
}
return this.GetMetadataForProperty(modelAccessor, containerType, propertyDescriptor);
Run Code Online (Sandbox Code Playgroud)
}
protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor)
{
IEnumerable<Attribute> attributes = this.FilterAttributes(containerType, propertyDescriptor, propertyDescriptor.Attributes.Cast<Attribute>());
return this.CreateMetadata(attributes, containerType, modelAccessor, propertyDescriptor.PropertyType, propertyDescriptor.Name);
}
Run Code Online (Sandbox Code Playgroud)
如果您AssociatedMetadataProvider在所提供的链接中按原样对其进行子类化,则首选的可扩展性点是CreateMetadata方法,因为该AssociatedMetadataProvider.GetMetadataForProperty()方法会预先验证方法的合同CreateMetadata().这样,您就知道如果您的CreateMetadata()方法中存在错误,您已经知道错误的来源在您的方法中,而不是在传递给它的参数中.
此外,这是FilterAttributes()方法的来源,如果你想知道:
protected virtual IEnumerable<Attribute> FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable<Attribute> attributes)
{
if (!typeof(ViewPage).IsAssignableFrom(containerType) && !typeof(ViewUserControl).IsAssignableFrom(containerType))
{
return attributes;
}
return attributes.Where<Attribute>(delegate (Attribute a) {
return !(a is ReadOnlyAttribute);
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1418 次 |
| 最近记录: |