asp.net-mvc-2 – ASP.NET MVC2 ModelMetadataProviders:重写CreateMetadata()和GetMetadataForProperty()之间有什么区别?

MetadataProviders开始,我很想探索框架的扩展点.我目前已经成功实施了 populating ModelMetadata.IsRequired property using 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);

}

protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor,PropertyDescriptor propertyDescriptor) 
{
   IEnumerable<Attribute> attributes = this.Filterattributes(containerType,propertyDescriptor,propertyDescriptor.Attributes.Cast<Attribute>());
   return this.CreateMetadata(attributes,modelAccessor,propertyDescriptor.PropertyType,propertyDescriptor.Name);
}

如果您正在将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);
    });
}

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....