ASP.NET MVC Model绑定(三)

前言

看过前两篇的朋友想必对Model绑定有个大概的了解,然而MVC框架给我们提供了更高的可扩展性的提供程序编程模式,也就是本篇的主题了,会讲解一下Model绑定器提供程序的实现以及解决一下上篇遗留的问题。

第一个问题是ModelBinderProviderCollection类型的执行过程?

还有个本篇的问题就是同样的向系统上下文中注册Model绑定器和Model绑定器提供程序,哪一个优先级更高?

Model绑定

  • IModelBinder、自定义Model绑定器简单实现
  • Model绑定器在MVC框架中的位置
  • MVC中的默认Model绑定器生成过程
  • IModelBinderProvider的简单应用
  • IValueProvider在MVC框架中生成的位置以及过程
  • IValueProvider的应用场景
  • IValueProvider的实现之NameValueCollectionValueProvider

IModelBinderProvider的简单应用

首先我们先看一下IModelBinderProvider类型的定义,代码1-1:。

代码1-1

    public interface IModelBinderProvider
{
// 摘要:
// 返回指定类型的模型联编程序。
//
// 参数:
// modelType:
// 模型的类型。
//
// 返回结果:
// 指定类型的模型联编程序。
IModelBinder GetBinder(Type modelType);
}

在代码1-1中我们看出,其中的GetBinder()方法是根据ViewModel的类型来做一些操作,最后返回Model绑定器。现在我们自定义实现一个Model绑定器提供程序代码1-2。

代码1-2

using System.Web.Mvc;
using ConsoleApplication2; namespace MvcApplication.Infrastructure
{
public class MyCustomModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (modelType == null)
{
throw new ArgumentNullException("modelType");
}
if (modelType == typeof(Customer))
{
//返回对应Customer类型的Model绑定器
}
return null;
}
}
}

在代码1-2中我们根据modelType判断是否是Customer类型,然后返回对应Customer类型的Model绑定器。为什么这里的实现是空的,因为我想把我们前面讲解过的IoC框架用起来,让Model绑定器提供程序跟Model绑定器解除耦合,想把IoC框架的应用定义在当前系统的上下文中,我们看一下代码实现,代码1-3。

代码1-3

using System.Web.Mvc;
using Ninject;
using System.ComponentModel;
using System.ComponentModel.Design;
using MvcApplication.Infrastructure.NinjectControllerPart; namespace MvcApplication
{
public class MVCSystemContext
{
private static MVCSystemContext _MVCSystemContext; public static MVCSystemContext Context
{
get
{
if (_MVCSystemContext == null)
{
_MVCSystemContext = new MVCSystemContext();
}
return _MVCSystemContext;
}
} private ServiceContainer _serviceContainer; private MVCSystemContext()
{
_serviceContainer = new ServiceContainer();
_serviceContainer.AddService(typeof(NinjectController),NinjectController.Instance);
} public NinjectController NinjectController
{
get
{
return (NinjectController)_serviceContainer.GetService(typeof(NinjectController));
}
} }
}

代码1-3当中就是我定义的当前系统上下文了,只不过这个是给自己用的,上下文对象中想必是不会把所用到的所有数据或者是功能都添加在里面的,只是添加个引用而已,如代码1-3中的NinjectController属性,NinjectController属性对应的类型就是NinjectController类型,NinjectController类型的作用就是提供IoC框架的功能,我们看一下代码1-4中对于NinjectController类型的定义。

代码1-4

using Ninject;

namespace MvcApplication.Infrastructure.NinjectControllerPart
{
public class NinjectController
{
private static NinjectController _Instance; public static NinjectController Instance
{
get
{
return _Instance = new NinjectController();
}
} private IKernel _ninjectKernel; private NinjectController()
{
_ninjectKernel = new StandardKernel();
} public void AddKernelBind<T, U>()where U:T
{
_ninjectKernel.Bind<T>().To<U>();
} public T GetValueType<T>(Type keyType)
{
var valueType = _ninjectKernel.Get(keyType);
return (T)valueType;
}
}
}

其中对于Ninject这个IoC框架进行了一个最基础的功能封装,有的朋友可能会问为什么不公开个一个属性,何必这样多此一举,因为我对Ninject的使用也不是很熟练,对于这部分的封装我只是让其简单的公开了两个功能,一个是绑定一个是获取值,这样让这部分内容还在我的可控范围内,如果是公开属性的话,其他人的胡乱使用导致错误的话是不可控的。

切回主题,这样基础定义好了过后,我们再修改1-2中的代码,把具体实现给加上,示例代码1-5所示。

代码1-5

if (modelType == typeof(Customer))
{
//返回对应Customer类型的Model绑定器
return MVCSystemContext.Context.NinjectController.GetValueType<IModelBinder>(typeof(IModelBinder));
}

可以看到代码1-5中,根据我们自定义上下文中的提供的IoC功能获取到绑定在IoC框架中的值,那么绑定又是在哪里呢?跟ASP.NET MVC Model绑定(一)所演示的那样,还是在项目的Global.asax文件中的MvcApplication类型的Application_Start()方法中添加如代码1-6。

代码1-6

MVCSystemContext.Context.NinjectController.AddKernelBind<IModelBinder, Binders.MyCustomModelBinder>();
ModelBinderProviders.BinderProviders.Add(new MyCustomModelBinderProvider());

代码1-6分别做了两个操作,先是把对应Customer类型的Model绑定器注册到了我们自定义上下文的IoC中,然后再把针对处理Customer类型的Model绑定器提供程序注册到系统中。运行结果如图1.

图1

其中涉及到所有部分的代码和ASP.NET MVC Model绑定(一)篇幅中的一样,所以这里就没有列举了。

在此我们根据上篇中最后图2所示的那样,可以判断出ModelBinderProviderCollection类型的执行过程是根据当前ParameterDescriptor类型所提供的Model类型对比我们注册到或者是系统默认提供的Model绑定器提供程序集合,如果有是针对ParameterDescriptor类型所提供的Model类型(上述示例中是Customer类型)则会有Model绑定器的返回,然后再根据Model绑定器进行Model绑定。

好了现在第一个问题解决了,来解决第二个问题。来看代码1-7所示。

代码1-7

    public class MyCustomModelBinder:IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new Customer()
{
CustomerID = "",
Name = "测试人员",
RegistrationDate = DateTime.Now,
Address = new Address()
{
AddressName = "天空之城"
}
};
}
} public class MyCustomModelBinder_Test : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new Customer()
{
CustomerID = "",
Name = "测试人员",
RegistrationDate = DateTime.Now,
Address = new Address()
{
AddressName = "这里是根据Model绑定器绑定执行的Model"
}
};
}
}

看到代码1-7中的MyCustomModelBinder_Test 类型内部Customer类型实例内部的AddressName值已经更改的和之前的不一样了。再看一下注册端的修改,示例代码1-8。

代码1-8

ModelBinders.Binders.Add(typeof(Customer), new Binders.MyCustomModelBinder_Test());
MVCSystemContext.Context.NinjectController.AddKernelBind<IModelBinder, Binders.MyCustomModelBinder>();
ModelBinderProviders.BinderProviders.Add(new MyCustomModelBinderProvider());

代码1-8中,我们把新定义的MyCustomModelBinder_Test 类型注册到了系统的Model绑定器集合中,看一下究竟是哪一个级别更高一点。

来看运行结果图2

图2

看到图2这个结果,想必已经知道了是哪个级别更高一点了。

作者:金源

出处:http://www.cnblogs.com/jin-yuan/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

ASP.NET MVC Model绑定(三)的更多相关文章

  1. ASP.NET MVC Model验证(三)

    ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...

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

    ModelBinder——ASP.NET MVC Model绑定的核心 Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数.通过前面的介绍我们知道Action方法的参数通过 ...

  3. ASP.NET MVC Model绑定(六)

    ASP.NET MVC Model绑定(六) 前言 前面的篇幅对于IValueProvider的使用做个基础的示例讲解,但是没并没有对 IValueProvider类型的实现做详细的介绍,然而MVC框 ...

  4. ASP.NET MVC Model绑定(五)

    ASP.NET MVC Model绑定(五) 前言 前面的篇幅对于IValueProvider的获取位置和所处的生成过程做了讲解,本篇将会对IValueProvider的使用做个基础的示例讲解,读完本 ...

  5. ASP.NET MVC Model绑定(四)

    ASP.NET MVC Model绑定(四) 前言 前面的篇幅对于Model绑定器IModelBinder以及实现类型.Model绑定器提供程序都作了粗略的讲解,可以把Model绑定器想象成一个大的容 ...

  6. ASP.NET MVC Model绑定(二)

    ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...

  7. ASP.NET MVC Model绑定(一)

    ASP.NET MVC Model绑定(一) 前言 ModelMetadata系列的结束了,从本篇开始就进入Model绑定部分了,这个系列阅读过后你会对Model绑定有个比较清楚的了解, 本篇对于Mo ...

  8. ASP.NET MVC Model元数据(三)

    ASP.NET MVC Model元数据(三) 前言 在上篇中我们大概的讲解了Model元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会 ...

  9. ASP.NET MVC Model绑定

    ASP.NET MVC Model绑定(一) 前言 ModelMetadata系列的结束了,从本篇开始就进入Model绑定部分了,这个系列阅读过后你会对Model绑定有个比较清楚的了解, 本篇对于Mo ...

随机推荐

  1. 异步任务队列Celery在Django中的使用

    前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务.在同事的指引下接触了Celery这个异步任务队 ...

  2. ASP.NET Aries 入门开发教程4:查询区的下拉配置

    背景: 今天去深圳溜达了一天,刚回来,看到首页都是微软大法好,看来离.NET的春天就差3个月了~~ 回到正题,这篇的教程讲解下拉配置. 查询区的下拉配置: 1:查询框怎么配置成下拉? 在配置表头:格式 ...

  3. myeclipse学习总结一(在MyEclipse中设置生成jsp页面时默认编码为utf-8编码)

    1.每次我们在MyEclispe中创建Jsp页面,生成的Jsp页面的默认编码是"ISO-8859-1".在这种情况下,当我们在页面中编写的内容存在中文的时候,就无法进行保存.如下图 ...

  4. 按需加载.js .css文件

    首先,理解按需加载当你需要用到某个js里面的函数什么鬼,或者某个css里的样式的时候你才开始加载这个文件. 然后是怎样实现的,简单来说就是在js中动态的createElem<script> ...

  5. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  6. 前端学HTTP之实体和编码

    前面的话 每天都有各种媒体对象经由HTTP传送,如图像.文本.影片以及软件程序等.HTTP要确保它的报文被正确传送,识别.提取以及适当处理.为了实现这些目标,HTTP使用了完善的标签来描述承载内容的实 ...

  7. Javacript实现字典结构

    字典是一种用[键,值]形式存储元素的数据结构.也称作映射,ECMAScript6中,原生用Map实现了字典结构. 下面代码是尝试用JS的Object对象来模拟实现一个字典结构. <script& ...

  8. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  9. Android之DOM解析XML

    一.DOM解析方法介绍 DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树,检索所需数据.分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息 ...

  10. Redis配置文件redis.conf

    1.地址 2.Units单位 1 配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit 2 对大小写不敏感 3.includes包含