ASP.NET MVC三个重要的描述对象:ParameterDescriptor

Model绑定是为作为目标Action的方法准备参数列表的过程,所以针对参数的描述才是Model绑定的核心。在ASP.NET MVC应用编程接口中,服务于Model绑定的参数元数据通过ParameterDescriptor类型来表示,而ActionDescriptor的GetParameters方法返回的就是一个ParameterDescriptor数组。

如下面的代码片断所示,ParameterDescriptor同样实现了ICustomAttributeProvider接口提供应用在相应参数上的特性。ParameterDescriptor的只读属性ActionDescriptor表示描述所在Action方法的ActionDescriptor对象。属性ParameterName、ParameterType和DefaultValue分别表示参数的名称、类型和默认值。

   1: public abstract class ParameterDescriptor : ICustomAttributeProvider
   2: {   
   3:     public virtual object[] GetCustomAttributes(bool inherit);
   4:     public virtual object[] GetCustomAttributes(Type attributeType, bool inherit);
   5:     public virtual bool IsDefined(Type attributeType, bool inherit);
   6:     
   7:     public abstract ActionDescriptor ActionDescriptor { get; }
   8:     public abstract string ParameterName { get; }
   9:     public abstract Type ParameterType { get; }
  10:     public virtual object DefaultValue { get; }
  11:  
  12:     public virtual ParameterBindingInfo BindingInfo { get; }
  13: }

ParameterDescriptor的只读属性BindingInfo表示的System.Web.Mvc.ParameterBindingInfo对象封装一些信息用于控制请求数据与参数的绑定行为。如下面的代码片断所示,抽象类ParameterBindingInfo具有四个属性,其中类型为IModelBinder的Binder属性返回的ModelBinder对象是整个Model绑定的核心,我们将在本章后续部分进行单独介绍。

   1: public abstract class ParameterBindingInfo
   2: {
   3:     public virtual IModelBinder Binder { get; }
   4:     
   5:     public virtual ICollection<string> Include { get; }
   6:     public virtual ICollection<string> Exclude { get; }
   7:     public virtual string Prefix { get; }
   8: }

如果参数类型是一个复杂类型,默认情况下会绑定其所有公共可读写属性,而两个ICollection<string>类型的属性Include和Exclude表示显示设置的参与/不参与绑定的属性名称列表。在默认情况下,请求数据与参数之间严格按照名称进行绑定,但是有时候请求数据名称具有相应的前缀,这个前缀体现在ParameterBindingInfo的Prefix属性上。

ReflectedParameterDescriptor

原生的ParameterBindingInfo是通过针对表示参数的ParameterInfo进行反射获得,这样的ParameterBindingInfo通过ReflectedParameterDescriptor类型表示。如下面的代码片断所示,这个ParameterInfo对象通过只读属性ParameterInfo表示,并在构造函数中被初始化。

   1: public class ReflectedParameterDescriptor : ParameterDescriptor
   2: {   
   3:     public ReflectedParameterDescriptor(ParameterInfo parameterInfo, ActionDescriptor actionDescriptor);
   4:     public override object[] GetCustomAttributes(bool inherit);
   5:     public override object[] GetCustomAttributes(Type attributeType, bool inherit);
   6:     public override bool IsDefined(Type attributeType, bool inherit);
   7:     
   8:     public override ActionDescriptor ActionDescriptor { get; }
   9:     public override ParameterBindingInfo BindingInfo { get; }
  10:     public override object DefaultValue { get; }
  11:     public override string ParameterName { get; }
  12:     public override Type ParameterType { get; }
  13:     
  14:     public ParameterInfo ParameterInfo { get; }
  15: }

ReflectedParameterDescriptor的BindingInfo属性返回的是一个ReflectedParameterBindingInfo对象,这是一个内部类型。该BindingInfo的Include、Exclude和Prefix属性来源于对应用在参数上的BindAttribute特性的解析。如下面的代码片断所示,BindAttribute中同样定义了这三个属性,其中Include和Exclude为通过逗号作为分隔符的属性名称列表。

   1: [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
   2: public sealed class BindAttribute : Attribute
   3: {
   4:     public bool IsPropertyAllowed(string propertyName);   
   5:     
   6:     public string Include { get; set; }
   7:     public string Exclude { get; set; }
   8:     public string Prefix { get; set;}
   9: }

布尔返回类型的IsPropertyAllowed方法用于判断指定的属性是否允许绑定,当指定在属性名在Include列表中(或者Include列表为空)并且不在Exclude列表的情况下返回True,否则返回False。

ASP.NET MVC三个重要的描述对象:ControllerDescriptor ASP.NET MVC三个重要的描述对象:ActionDescriptor ASP.NET MVC三个重要的描述对象:ControllerDescriptor与ActionDescriptor的创建机制 ASP.NET MVC三个重要的描述对象:ParameterDescriptor

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版3.3节栈布局之局部变量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

861
来自专栏一个会写诗的程序员的博客

Kotlin 中的集合类排序Kotlin 开发者社区

Kotlin使用扩展方法构建在Java Collection框架之上。这大大提高了可用性和可读性,而无需第三方依赖,如Apache Commons或Guava。

1575
来自专栏令仔很忙

限制字符串输入——正则表达式(VB.NET)

在做机房收费系统的时候,几乎所有的窗体上都存在着文本框或者组合框,当用户进行操作的时候,首先要判断是否为空,然后再对各种属性进行判断,比如;卡号、学号、金额等...

2701
来自专栏盛国存的专栏

A Bite of GoLang(上)

A bite of GoLang(浅尝GoLang),本文只是Go语言的冰山一角,本文包含作者学习Go语言期间积累的一些小的经验,同时为了方便让读者了解到Go语...

55310
来自专栏HansBug's Lab

1901: Zju2112 Dynamic Rankings

1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Submit: ...

2776
来自专栏Pythonista

Python3编程技巧

Microsoft Excel是Microsoft为使用Windows和Apple Macintosh操作系统的计算机编写的一款电子表格软件。直观的界面、出色的...

1062
来自专栏机器学习入门

LWC 58:724. Find Pivot Index

LWC 58:724. Find Pivot Index 传送门:724. Find Pivot Index Problem: Given an array ...

2018
来自专栏Python爱好者

Python高效编程(一)

2259
来自专栏Golang语言社区

go语言中的数组切片:特立独行的可变数组

初看go语言中的slice,觉得是可变数组的一种很不错的实现,直接在语言语法的层面支持,操作方面比起java中的ArrayList方便了许多。但是在使用了一段时...

3434
来自专栏jeremy的技术点滴

写py2、py3兼容的代码

8858

扫码关注云+社区

领取腾讯云代金券