Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >ModelBinder——ASP.NET MVC Model绑定的核心

ModelBinder——ASP.NET MVC Model绑定的核心

作者头像
蒋金楠
发布于 2018-02-08 07:18:50
发布于 2018-02-08 07:18:50
2.4K0
举报
文章被收录于专栏:大内老A大内老A

Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数。通过前面的介绍我们知道Action方法的参数通过ParameterDescriptor来描述,ParameterDescriptor的BindingInfo属性表示的ParameterBindingInfo对象具有一个名为ModelBinder的组件用于完成针对当前参数的Model绑定。ModelBinder可以看成是整个Model绑定系统的核心,我们先来认识这个重要的组件。[本文已经同步到《How ASP.NET MVC Works?》中]

目录 一、 ModelBinder 二、CustomModelBinderAttribute与ModelBinderAttribute 三、ModelBinders 四、ModelBinderProvider

一、 ModelBinder

用于进行Model绑定的ModelBinder对象实现了接口IModelBinder。如下面的代码片断所示,IModelBinder接口具有唯一的BindModel方法用于实现针对某个参数的绑定操作,该方法的返回值表示的就是最终作为参数值的对象。

代码语言:js
AI代码解释
复制
   1: public interface IModelBinder
   2: {
   3:     object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);
   4: }

IModelBinder的BindModel方法接受两个参数,一个是表示当前的Controller上下文,另一个是表示针对当前Model绑定的上下文,通过类型ModelBindingContext表示。在Controller初始化的时候,Controller上下文已经被创建出来,所以我们只要能够针对当前的Model绑定创建相应的ModelBindingContext,我们就能使用基于某个参数的ModelBinder得到对应的参数值。关于ModelBindingContext的创建我们会在后续部分进行的单独介绍,我们先来介绍一下ModelBinder的提供机制。

二、CustomModelBinderAttribute与ModelBinderAttribute

如果针对某个参数的ParameterDescriptor具有相应的ModelBinder,那么它会被优先选择用于针对该参数的Model绑定,那么ParameterDescriptor的ModelBinder是如何来提供的呢?这是实际上设置一个具有如下定义的CustomModelBinderAttribute特性。抽象类CustomModelBinderAttribute定义了唯一的抽象方法GetBinder用于获取相应的ModelBinder对象。

代码语言:js
AI代码解释
复制
   1: [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct 
   2:     | AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
   3: public abstract class CustomModelBinderAttribute : Attribute
   4: {
   5:     public abstract IModelBinder GetBinder();
   6: }

在ASP.NET MVC应用编程接口中,CustomModelBinderAttribute具有一个具有如下定义的唯一继承类型ModelBinderAttribute。我们可以通过应用ModelBinderAttribute特性动态地选择用于Model绑定的ModelBinder类型。

代码语言:js
AI代码解释
复制
   1: [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Interface | 
   2:     AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class, 
   3:     AllowMultiple=false, Inherited=false)]
   4: public sealed class ModelBinderAttribute : CustomModelBinderAttribute
   5: {   
   6:     public ModelBinderAttribute(Type binderType);
   7:     public override IModelBinder GetBinder();
   8:  
   9:     public Type BinderType { [CompilerGenerated] get;  }
  10: }

从应用在ModelBinderAttribute类型上的AttributeUsageAttribute定义可以看出该特性不仅仅可以应用在参数上,也可以应用类型(接口、枚举、结构和类)上,这意味我们既可以将它应用在Action方法的某个参数上,也可以将它应用在某个参数的类型上。但是ParameterDescriptor只会解析应用在参数上的特性,所以应用在参数对象类型上的ModelBinderAttribute对它是无效的。

为了演示ModelBinderAttribute特性对ParameterDescriptor的影响,我们来进行一个简单的实例演示。在一个通过Visual Studio的ASP.NET MVC项目模板创建的空Web应用中定义了如下几个类型,其中FooModelBinder和BarModelBinder是显现了IModelBinder的自定义ModelBinder类型,而Foo、Bar和Baz是三个将被作为Action方法参数的数据类型,其中Bar上应用了ModelBinderAttribute特性并将ModelBinder类型设置为BarModelBinder。

代码语言:js
AI代码解释
复制
   1: public class FooModelBinder : IModelBinder
   2: {
   3:     public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   4:     {
   5:         throw new NotImplementedException();
   6:     }
   7: }
   8: public class BarModelBinder : IModelBinder
   9: {
  10:     public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  11:     {
  12:         throw new NotImplementedException();
  13:     }
  14: }
  15:  
  16: public class Foo { }
  17: [ModelBinder(typeof(BarModelBinder))]
  18: public class Bar { }
  19: public class Baz { }

然后再创建的默认HomeController中定义如下两个Action方法。DoSomething方法具有三个参数,类型分别是Foo、Bar和Baz,在第一个参数上应用了ModelBinderAttribute特性并将ModelBinder类型设置为FooModelBinder。

代码语言:js
AI代码解释
复制
   1: public class HomeController : Controller
   2: {
   3:     public void Index()
   4:     {
   5:         ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(typeof(HomeController));
   6:         ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(ControllerContext, "DoSomething");
   7:         IModelBinder foo = actionDescriptor.GetParameters().First(p => p.ParameterName == "foo").BindingInfo.Binder;
   8:         IModelBinder bar = actionDescriptor.GetParameters().First(p => p.ParameterName == "bar").BindingInfo.Binder;
   9:         IModelBinder baz = actionDescriptor.GetParameters().First(p => p.ParameterName == "baz").BindingInfo.Binder;
  10:  
  11:         Response.Write(string.Format("foo: {0}<br/>", null == foo? "N/A": foo.GetType().Name));
  12:         Response.Write(string.Format("bar: {0}<br/>", null == bar ? "N/A" : bar.GetType().Name));
  13:         Response.Write(string.Format("baz: {0}<br/>", null == baz ? "N/A" : baz.GetType().Name));
  14:     }
  15:  
  16:     public void DoSomething([ModelBinder(typeof(FooModelBinder))]Foo foo,Bar bar, Bar baz)
  17:     {}                
  18: }

在默认的Action方法Index中,我们针对HomeController类型的ReflectedControllerDescriptor对象并获取到用于描述Action方法DoSomething的ActionDescriptor对象。最后我们通过该ActionDescriptor对象得到用于描述其三个参数的ParameterDescriptor对象,并将其ModelBinder类西国内呈现出来。当我们运行该程序的时候,会在浏览器中产生如下的输出结果,可以看出对于分别应用在参数和参数类型上的ModelBinderAttribute特性,只有前者会对ParameterDescriptor的ModelBinder的选择造成影响。

代码语言:js
AI代码解释
复制
   1: foo: FooModelBinder
   2: bar: N/A
   3: baz: N/A

三、ModelBinders

如果我们不曾通过ModelBinderAttribute特性为某个Action方法参数的ModelBinder类型进行显式定制,默认采用的Model是通过静态类型ModelBinders来提供的。如下面的代码片断所示,ModelBinders具有一个静态只读属性Binders,表示当前注册ModelBinder列表,其类型为ModelBinderDictionary

代码语言:js
AI代码解释
复制
   1: public static class ModelBinders
   2: {   
   3:     public static ModelBinderDictionary Binders { get; }
   4: }
   5:  
   6: public class ModelBinderDictionary : 
   7:   IDictionary<Type, IModelBinder>, 
   8:   ICollection<KeyValuePair<Type, IModelBinder>>, 
   9:   IEnumerable<KeyValuePair<Type, IModelBinder>>, 
  10:   IEnumerable
  11: {    
  12:     //其他成员
  13:     public IModelBinder GetBinder(Type modelType);
  14:    public virtual IModelBinder GetBinder(Type modelType, bool fallbackToDefault);
  15: }

ModelBinderDictionary是一个以数据类型(Model类型)为Key,ModelBinder对象为Value的字典,即它定义了针对某种数据类型的ModelBinder。ModelBinderDictionary具有两个GetBinder方法重载用于获取针对某个数据类型的ModelBinder,布尔类型的参数fallbackToDefault表示在数据类型不存在的时候是否采用默认的ModelBinder,基于默认ModelBinder的后备机制会在第一个GetBinder方法重载中采用。在这里默认ModelBinder类型为DefaultModelBinder

在为某个参数获取相应的ModelBinder的时候,如果对应的ParameterDescriptor的ModelBinder不存在,则通过ModelBinders的静态属性Binders表示获取到当前注册的ModelBinder列表的ModelBinderDictionary对象,并将参数类型作为参数调用其GetBinder方法获取相应ModelBinder对象。

我们根据ModelBinder的提供机制对上面演示的实例进行相应的修改。我们在HomeConroller中添加了一个CheckModelBinder方法,三个参数分别表示用于描述相应Action方法的ActionDescriptor对象、参数名称和类型。在该方法中我们先获取到用于描述制定参数的ParameterDescriptor对象,如果它具有相应的ModelBinder,则将具体的类型名称输出,否则输出通过ModelBinders获取的针对参数类型的ModelBinder类型。

代码语言:js
AI代码解释
复制
   1: public class HomeController : Controller
   2: {
   3:     //其他成员
   4:     public void Index()
   5:     {
   6:         ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(typeof(HomeController));
   7:         ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(ControllerContext, "DoSomething");
   8:  
   9:         CheckModelBinder(actionDescriptor, "foo", typeof(Foo));
  10:         CheckModelBinder(actionDescriptor, "bar", typeof(Bar));
  11:         CheckModelBinder(actionDescriptor, "baz", typeof(Baz));           
  12:     }
  13:  
  14:     private void CheckModelBinder(ActionDescriptor actionDescriptor, string parameterName, Type modelType)
  15:     { 
  16:         ParameterDescriptor parameterDescriptor = actionDescriptor.GetParameters().First(p=>p.ParameterName == parameterName);
  17:         IModelBinder modelBinder = parameterDescriptor.BindingInfo.Binder ?? ModelBinders.Binders.GetBinder(modelType);
  18:         Response.Write(string.Format("{0}: {1}<br/>", parameterName, null == modelBinder ? "N/A" : modelBinder.GetType().Name));
  19:     }
  20: }

在Index方法中,我们调用CheckModelBinder方法将Action方法DoSomething的三个参数对应的ModelBinder类型呈现出来。当我们运行该程序的时候,在浏览器上会得到如下的输出结果,应用在类型Bar上的BarModelBinder会用于针对参数bar的Model绑定,而参数baz则会使用默认的DefaultModelBinder。

代码语言:js
AI代码解释
复制
   1: foo: FooModelBinder
   2: bar: BarModelBinder
   3: baz: DefaultModelBinder

对于上面的这个例子,由于数据类型Baz没有关联ModelBinder注册到通过ModelBinders的静态属性Binders表示的全局ModelBinder列表中,所以才导致DoSomething的baz参数采用默认的DefaultModelBinder。如果我们实现针对数据类型Baz进行了相应的ModelBinder注册,那么被注册的ModelBinder将会自动用于该类型参数的Model绑定。同样是针对上面演示的这个实例,我们定义了如下一个实现了IModelBinder的BazModelBinder。

代码语言:js
AI代码解释
复制
   1: public class BazModelBinder : IModelBinder
   2: {
   3:     public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   4:     {
   5:         throw new NotImplementedException();
   6:     }
   7: }

现在我们希望使用这个BazModelBinder用于针对所有类型为Bar的参数的Model绑定,那么我们可以通过Global.asax在应用启动的时候进行如下的ModelBinder注册。

代码语言:js
AI代码解释
复制
   1: public class MvcApplication : System.Web.HttpApplication
   2: {
   3:     //其他成员
   4:     protected void Application_Start()
   5:     {
   6:         //其他操作
   7:         ModelBinders.Binders.Add(typeof(Baz), new BazModelBinder());
   8:     }
   9: }

再次运行我们的程序,在浏览器中会得到如下的输出结果,从中可以清楚地看出我们注册的BazModelBinder并用于baz参数的Model绑定。

代码语言:js
AI代码解释
复制
   1: foo: FooModelBinder
   2: bar: BarModelBinder
   3: baz: BazModelBinder

四、ModelBinderProvider

ASP.NET MVC的Model绑定系统还涉及到另一个重要的组件ModelBinderProvider。顾名思义,ModelBinderProvider专门用于提供相应的ModelBinder对象,它们均实现了IModelBinderProvider面的代码片断所示,IModelBinderProvider接口定义了唯一的GetBinder方法用于根据数据类型获取相应的ModelBinder对象。不过在ASP.NET MVC现有的应用编程接口中并没有定义任何一个实现该接口的ModelBinderProvider类型。

代码语言:js
AI代码解释
复制
   1: public interface IModelBinderProvider
   2: {    
   3:     IModelBinder GetBinder(Type modelType);
   4: }

我们可以利用ModelBinderProviders为应用注册一组ModelBinderProvider对象为某个数据类型提供相应的ModelBinder。如下面的代码片断所示,静态类型ModelBinderProviders具有一个静态只读属性BinderProviders,其类型ModelBinderProviderCollection实际上是一个型ModelBinderProvider的集合,该集合表示针对当前应用的ModelBinderProvider列表。

代码语言:js
AI代码解释
复制
   1: public static class ModelBinderProviders
   2: {    
   3:     public static ModelBinderProviderCollection BinderProviders { get; }
   4: }
   5:  
   6: public sealed class ModelBinderProviderCollection : Collection<IModelBinderProvider>
   7: {
   8:     //省略成员
   9: }

通过ModelBinderProviders的静态属性BinderProviders表示的ModelBinderProvider列表最终被ModelBinderDictionary使用。如下面的代码片断所示,ModelBinderDictionary除了具有一个表示基于数据类型的ModelBinder字典(_innerDictionary字段)和一个默认ModelBinder(_defaultBinder)之外,还具有一个ModelBinderProvider列表(_modelBinderProviders字段)。

代码语言:js
AI代码解释
复制
   1: public class ModelBinderDictionary
   2: {
   3:     //其他成员
   4:     private IModelBinder _defaultBinder;
   5:     private readonly Dictionary<Type, IModelBinder> _innerDictionary;
   6:     private ModelBinderProviderCollection _modelBinderProviders;   
   7: }

当ModelBinderDictionary被创建的时候,通过ModelBinderProviders的静态属性BinderProviders表示的ModelBinderProvider列表会用于初始化_modelBinderProviders字段。围绕着ModelBinder的Model绑定系统中的核心组件之间的关系基本上可以通过下图所示的UML来表示。

当我们调用GetBinder或者指定数据类型对应的ModelBinder时,_innerDictionary字段表示的ModelBinder字典会被优先选择。如果数据类型在该字典中找不到,则选择使用通过_modelBinderProviders字段表示的ModelBinderProvider列表进行ModelBinder的提供。只有在两种ModelBinder提供方式均失败的情况下才会选择通过_innerDictionary字段表示的默认ModelBinder。也就是说,如果我们想为某个数据类型定制某种类型的ModelBinder,按照选择优先级具有如下几种方式供我们选择:

  • 将ModelBinderAttribute应用在Action方法的相应参数上并指定相应的ModelBinder类型,或者在参数上应用一个自定义的CustomModelBinderAttribute特性。
  • 通过ModelBinders的静态属性Binders实现针对基于某种数据类型的ModelBinder注册。
  • 自定义ModelBinderProvider实现基于某个数据类型的ModelBinder提供机制,并通过注册当通过ModelBinderProviders的静态属性BinderProviders表示的ModelBinderProvider列表中。
  • 将ModelBinderAttribute应用在数据类型上并制定相应的ModelBinder类型,或者在数据类型上应用一个自定义的CustomModelBinderAttribute特性。

前面三种方式的ModelBinder提供机制我们已经通过实例演示过了,现在我们来演示基于自定义ModelBinderProvider的ModelBinder提供机制。在前面的例子中我们为Foo、Bar和Baz这三种数据类型创建了相应的ModelBinder(FooModelBinder、BarModelBinder和BazModelBinder),现在我们创建如下一个自定义的ModelBinderProvider将两种(数据类型和ModelBinder对象)进行关联。

代码语言:js
AI代码解释
复制
   1: public class MyModelBinderProvider : IModelBinderProvider
   2: {
   3:     public IModelBinder GetBinder(Type modelType)
   4:     {
   5:         if (modelType == typeof(Foo))
   6:         {
   7:             return new FooModelBinder();
   8:         }
   9:         if (modelType == typeof(Bar))
  10:         {
  11:             return new BazModelBinder();
  12:         }
  13:         if (modelType == typeof(Baz))
  14:         {
  15:             return new BazModelBinder();
  16:         }
  17:         return null;
  18:     }
  19: }

现在我们需要通过利用Global.asax通过如下的方式在应用启动时将一个我们自定义的MyModelBinderProvider注册到通过ModelBinderProviders的静态属性BinderProviders表示的ModelBinderProvider列表中。

代码语言:js
AI代码解释
复制
   1: public class MvcApplication : System.Web.HttpApplication
   2: {
   3:     //其他成员
   4:     protected void Application_Start()
   5:     {
   6:         //其他操作
   7:        ModelBinderProviders.BinderProviders.Add(new MyModelBinderProvider());
   8:     }
   9: }

由于MyModelBinderProvider实现了针对Foo、Bar和Baz三种数据类型的ModelBinder的提供,所以我们可以将应用在Action方法参数和数据类型上的ModelBinderAttribute特性删除。再次运行我们的程序,会在浏览器中得到如下的输出结果,从中可以看到DoSomething方法的三个参数此时采用了我们期望的ModelBinder类型。

代码语言:js
AI代码解释
复制
   1: foo: FooModelBinder
   2: bar: BarModelBinder
   3: baz: BazModelBinder
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2012-05-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ASP.NET MVC5 ModelBinder
ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应。为了能够正确处理请求,Action的参数(如果有的话),必须在Action执行之前,根据相应的规则,把请求中所包含的数据提取出来并将映射为Action的参数值,这个过程就是ModelBinding。ModelBinding的作用就是为Action提供参数列表。
雪飞鸿
2018/09/05
1.4K0
ASP.NET MVC5 ModelBinder
通过实例模拟ASP.NET MVC的Model绑定机制:简单类型+复杂类型
总的来说,针对目标Action方法参数的Model绑定完全由组件ModelBinder来实现,在默认情况下使用的ModelBinder类型为DefaultModelBinder,接下来我们将按照逐层深
蒋金楠
2018/01/15
1.9K0
通过实例模拟ASP.NET MVC的Model绑定机制:简单类型+复杂类型
通过极简模拟框架让你了解ASP.NET Core MVC框架的设计与实现[下篇]:参数绑定
模拟框架到目前为止都假定Action方法是没有参数的,我们知道MVC框架对Action方法的参数并没有作限制,它可以包含任意数量和类型的参数。一旦将“零参数”的假设去除,ControllerActionInvoker针对Action方法的执行就变得没那么简单了,因为在执行目标方法之前需要绑定所有的参数。MVC框架采用一种叫做“模型绑定(Model Binding)”的机制来绑定目标Action方法的输出参数,这可以算是MVC框架针对请求执行流程中最为复杂的一个环节,为了让读者朋友们对模型绑定的设计和实现原理有一个大致的了解,模拟框架提供一个极简版本的实现。
蒋金楠
2020/04/01
1.3K0
通过极简模拟框架让你了解ASP.NET Core MVC框架的设计与实现[下篇]:参数绑定
快速入门系列--MVC--04模型
model元数据    闲来继续学习蒋金楠大师的ASP.NET MVC框架揭秘一书,当前主要阅读的内容是Model元数据的解析,即使是阅读完的现在,仍然有不少细节不是特别明白。好在这部分内容主要是关于Razor引擎的呈现的,通过注解的方式对Model进行自定的修饰,最终使得页面在渲染时(即从cshtml文件转化为html时),相关的数据能够按照指定的形式转化并显示。由于接下来的项目中不再打算使用Razor引擎,该引擎虽然很不错,但也有一些问题,例如存在HTML5代码与HtmlHelper的混写,使得UI层
用户1216676
2018/01/24
9460
快速入门系列--MVC--04模型
ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model类型及其属性上的ValidationAttribute才有效。如果我们能够将ValidationAttribut
蒋金楠
2018/01/15
7880
ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
MVC项目开发中那些用到的知识点(MVC IModelBinder)
本节主要来记录一下客户端发送请求的参数自动绑定为强类型的成员属性或方法参数也就是Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数。
aehyok
2019/02/25
8020
ASP.NET MVC三个重要的描述对象:ParameterDescriptor
Model绑定是为作为目标Action的方法准备参数列表的过程,所以针对参数的描述才是Model绑定的核心。在ASP.NET MVC应用编程接口中,服务于Model绑定的参数元数据通过ParameterDescriptor类型来表示,而ActionDescriptor的GetParameters方法返回的就是一个ParameterDescriptor数组。 如下面的代码片断所示,ParameterDescriptor同样实现了ICustomAttributeProvider接口提供应用在相应参数上的特性。P
蒋金楠
2018/01/15
7340
ASP.NET Core 2.2 十九. 你扔过来个json,我怎么接
  前文说道了Action的激活,这里有个关键的操作就是Action参数的映射与模型绑定,这里即涉及到简单的string、int等类型,也包含Json等复杂类型,本文详细分享一下这一过程。
FlyLolo
2019/03/11
7710
ASP.NET Core 2.2  十九. 你扔过来个json,我怎么接
ASP.NET MVC是如何运行的(4): Action的执行
作为Controller基类ControllerBase的Execute方法的核心在于对Action方法的执行和作为方法返回的ActionResult的执行,两者的执行是通过一个叫做ActionInvoker的组件来完成的。 一、ActionInvoker 我们同样为ActionInvoker定义了一个接口IActionInvoker。如下面的代码片断所示,该接口定义了一个唯一的方法InvokeAction用于执行指定名称的Action方法,该方法的第一个参数是一个表示基于当前Controller上下文的C
蒋金楠
2018/02/07
1.1K0
Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html。
aehyok
2018/08/31
1.4K0
Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
ASP.NET WebAPI 中的参数绑定
当 WebAPI 调用 Controller 上的方法时, 必须为其参数赋值, 这个过程就是参数绑定。 本文介绍 WebAPI 如何绑定参数, 以及如何进行自定义。
beginor
2020/08/10
2.6K0
ASP.NET MVC三个重要的描述对象:ControllerDescriptor和ActionDescriptor的创建
不论是用于描述Controller的ControllerDescriptor,还是用于描述Action方法的ActionDescriptor,都具有同步和异步两个版本,那么这些不同类型的ControllerDescriptor的ActionDescriptor是在什么情况下创建的呢? 一、ControllerActionInvoker与AsyncControllerActionInvoker ControllerDescriptor的创建设计到一个重要的名为ActionInvoker的组件,顾名思义,Act
蒋金楠
2018/01/15
6660
ASP.NET MVC三个重要的描述对象:ControllerDescriptor和ActionDescriptor的创建
深入探讨ASP.NET MVC的筛选器
在ActionInvoker对Action的执行过程中,除了通过利用ActionDescriptor对Action方法的执行,以及之前进行的Model绑定与验证之外,还具有一个重要的工作,那就是对相关筛选器(Filter)的执行。ASP.NET MVC的筛选器是一种基于AOP(面向方面编程)的设计,我们将一些非业务的逻辑实现在相应的筛选器中,然后以一种横切(Crosscutting)的方式应用到对应的Action方法。当Action方法执行前后,这些筛选器会自动执行。ASP.NET MVC提供了四种类型的筛
蒋金楠
2018/01/15
1.3K0
深入探讨ASP.NET MVC的筛选器
ASP.NET MVC三个重要的描述对象:ActionDescriptor
在Model绑定过程中会通过激活的Controller类型创建用于描述它的ControllerDescriptor对象。Controller是一组Action方法的集合,而每一个Action通过Act
蒋金楠
2018/01/15
8220
ASP.NET Web API编程——模型验证与绑定
1.模型验证 使用特性约束模型属性 可以使用System.ComponentModel.DataAnnotations提供的特性来限制模型。 例如,Required特性表示字段值不能为空,Range特性限制数值类型的范围。 对实体类使用特性后,可以使用ModelState.IsValid来判断验证是否通过。 例: 实体: public class DataModel { public int Id { get; set; } public string Field1Nam
甜橙很酸
2018/04/18
3K0
ASP.NET Web API编程——模型验证与绑定
ASP.NET MVC三个重要的描述对象:ControllerDescriptor
ASP.NET MVC应用的请求都是针对某个Controller的某个Action方法,所以对请求的处理最终体现在对目标Action方法的执行。而Action方法具有相应的参数,所以在方法执行之前必须根据相应的规则从请求中提取相应的数据并将其转换为Action方法参数列表,我们将这个过程称为Model绑定。在ASP.NET MVC应用编程接口中,Action方法某个参数的元数据通过ParameterDescriptor表示,而两个相关的类型ControllerDescriptor和ActionDescrip
蒋金楠
2018/01/15
7150
ASP.NET MVC涉及到的5个同步与异步,你是否傻傻分不清楚?[下篇]
关于ASP.NET MVC对请求的处理方式(同步或者异步)涉及到的五个组件,在《上篇》中我们谈了三个(MvcHandler、Controller和ActionInvoker),现在我们来谈余下的两个,
蒋金楠
2018/01/15
5640
ASP.NET MVC涉及到的5个同步与异步,你是否傻傻分不清楚?[下篇]
jquery easyui datagrid mvc server端分页排序筛选的实现
1自定义一个ModelBinder public class filterRule { public string field { get; set; } public string op { get; set; } public string value { get; set; } } public class dataGridFilter { public dataGridFilter()
阿新
2018/04/12
1.2K0
通过实例模拟ASP.NET MVC的Model绑定机制:数组
[续《通过实例模拟ASP.NET MVC的Model绑定机制:简单类型+复杂类型]》]基于数组和集合类型的Model绑定机制比较类似,对于绑定参数类型或者参数类型的某个属性为数组或者集合,如果Valu
蒋金楠
2018/01/15
3.3K0
在 ASP.NET Core Web API 中处理 Patch 请求
在 ASP.NET Core Web API 中,由于 C# 是一种静态语言(dynamic 在此不表),当我们定义了一个类型用于接收 HTTP Patch 请求参数的时候,在 Action 中无法直接从实例中得知客户端提供了哪些参数。
郑子铭
2023/08/29
2790
在 ASP.NET Core Web API 中处理 Patch 请求
推荐阅读
相关推荐
ASP.NET MVC5 ModelBinder
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档