大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > ASP.NET技巧 > ASP.NET Web API Model-ModelMetadata

ASP.NET Web API Model-ModelMetadata(2)

关键词:WebNETASPModelMetadataMode  阅读(1309) 赞(15)

[摘要]本文是对ASP.NET Web API Model-ModelMetadata的讲解,对学习ASP.NET编程技术有所帮助,与大家分享。

根据图1所示的这样,然后我们再看代码1-2的实现,最后我们看一下执行的结果。

图2

图2中所示就是从客户端和浏览器共同访问返回的结果值,都是一样的。

下面我们来讲解一下相关的对象类型。

图3

我们先来看ModelMetadata类型,从图3中我们可以看到ModelMetadata类型在命名空间System.Web.Http.Metadata下,我们就先来看一下ModelMetadata的定义,

示例代码1-3

    public class ModelMetadata
    {
        public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
        public virtual Dictionary<string, object> AdditionalValues { get; }
        public Type ContainerType { get; }
        public virtual bool ConvertEmptyStringToNull { get; set; }
        public virtual string Description { get; set; }
        public virtual bool IsComplexType { get; }
        public bool IsNullableValueType { get; }
        public virtual bool IsReadOnly { get; set; }
        public object Model { get; set; }
        public Type ModelType { get; }
        public virtual IEnumerable<ModelMetadata> Properties { get; }
        public string PropertyName { get; }
        protected ModelMetadataProvider Provider { get; set; }
        public string GetDisplayName();
        public virtual IEnumerable<System.Web.Http.Validation.ModelValidator> GetValidators(IEnumerable<System.Web.Http.Validation.ModelValidatorProvider> validatorProviders);
    }

代码1-3中定义了ModelMetadata类型,我们就从构造函数开始讲解。

在构造函数中有五个参数,这些参数有的是跟属性对应的,就拿第一个参数ModelMetadataProvider类型来说,它对应的就是ModelMetadata类型中的Provider属性,有的朋友会问这个属性干什么的?还记得上面的示例中讲过,在Model元数据是复杂类型的时候从Properties属性中获取当前所表示类型下的Model元数据,就是在获取的时候拿什么生成?就是用的这个Provider属性对应的元数据提供程序,这里也讲一下Properties属性,从它的定义中可以看到,是个IEnumerable<ModelMetadata>类型的属性,也就是为什么上面我所说的以树形结构的方式展现给我们看的原因。下面说到构造函数中的第二个参数实例类型,就是这个元数据对象所表示的、所对应的类型的容器类型,第三个参数比较有意思,是个Func<Object>委托,它是用来获取当前元数据对象所表示类型的实例值,这也就是ModelMetadata类型中Model属性的属性值的由来,第四个参数就是当前元数据对应的对象类型,也就是对应着ModelMetadata类型中ModelType属性值,最后一个参数表示属性名称,也对应着ModelMetadata类型中的PropertyName属性值。

下面说说ModelMetadata类型中的其他属性值,AdditionalValues表示容器属性,可自行添加任何额外值在其中以键值队的方式表示,这个很多框架中设计对象时都会有,可以是object类型,不过这里使用键值队来表示。

IsComplexType属性表示当前Model元数据对象所表示的类型是否是复杂类型,这个怎么判断的呢?

    public virtual bool IsComplexType
    {
        get
        {
            return !TypeHelper.HasStringConverter(this.ModelType);
        }
    }

就是看类型是否可以转换为String类型。

IsReadOnly属性下面再讲,因为在初始化一个Model元数据的时候得到的信息只有这么多,而IsReadOnly属性则是通过ModelAttribute来控制的。

我们再来看一下ModelMetadataProvider

示例代码1-4

    public abstract class ModelMetadataProvider
    {
        protected ModelMetadataProvider();
        public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
        public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
        public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
    }

在代码1-4中我们看到Model元数据提供程序ModelMetadataProvider类型中有三个抽象方法,本身也是抽象类,这三个方法的含义来给大家解释一下。

GetMetadataForProperties()方法是根据容器实例、容器的类型来获取容器中所有属性的元数据类型。

GetMetadataForProperty()方法则是根据一个获取容器实例的委托、容器类型,和要返回的属性元数据的属性名称。

GetMetadataForType()方法就是根据一个类型来获取这个类型所所表示的元数据,不过委托参数是要能获取到这个类型的实例。

下面我们回到代码1-2中,在我们获取Model元数据提供程序的地方,上面也说过了我们是从哪里获取到的,现在我们就来看看具体的类型,

示例代码1-5

this.SetSingle<ModelMetadataProvider>(new DataAnnotationsModelMetadataProvider());

那我们就来看看DataAnnotationsModelMetadataProvider类型中的定义。



相关评论