ASP.NET MVC Model绑定(五)

简介:

ASP.NET MVC Model绑定(五)

前言

前面的篇幅对于IValueProvider的获取位置和所处的生成过程做了讲解,本篇将会对IValueProvider的使用做个基础的示例讲解,读完本篇你将会对IValueProvider有个更清晰的印象。

 

Model绑定

  • IModelBinder、自定义Model绑定器简单实现

  • Model绑定器在MVC框架中的位置

  • MVC中的默认Model绑定器生成过程

  • IModelBinderProvider的简单应用

  • IValueProvider在MVC框架中生成的位置以及过程

  • IValueProvider的应用场景

  • IValueProvider的实现之NameValueCollectionValueProvider

 

IValueProvider的应用场景

图1

图1中所示的就是本篇所要演示的IValueProvider的简单示例了。这里不对图中的类型做讲解,看下文的示例代码自会知晓。

首先红色方框所示的就是主要流程了,我们先来实现一下:

1.  控制器方法的定义

代码1-1

1
2
3
4
5
6
7
8
9
10
11
12
13
namespace  MvcApplication.Controllers
{
     public  class  ValueProviderCaseController : Controller
     {
 
         public  ActionResult Index( string  ValueProviderCase)
         {
             ViewBag.value = ValueProviderCase;
             return  View();
         }
 
     }
}

代码1-1中很简单的定义了一个Index()方法,并且参数类型(Model类型)为string类型,参数名称(Model名称)为ValueProviderCase,请大家记住这个参数名称后面会用到的。

 

2.视图呈现端代码

代码1-2

1
2
3
4
5
6
@{
     ViewBag.Title = "Index";
}
 
< h2 >Index</ h2 >
< p >@ViewBag.value</ p >

代码1-2为视图呈现端代码,这里用了ViewBag动态类型来传值。

从图1中可以看到,在执行控制器方法之前,首先要获取Model绑定器,然后是执行Model绑定器,我们先把获取Model绑定器的部分流程放一放,先来看一下执行Model绑定器的流程。

 

3.自定义值提供程序的定义

从图1中看到,在执行Model绑定器的流程中,最后是执行的自定义值提供程序MyCustomValueProvider,这里我们先不管其他的,看一下这个类型的定义:

代码1-3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using  System.Web.Mvc;
 
namespace  MvcApplication.ValueProvider
{
     public  class  MyCustomValueProvider:IValueProvider
     {
         public  bool  ContainsPrefix( string  prefix)
         {
             if  (prefix ==  "ValueProviderCase" )
             {
                 return  true ;
             }
             return  false ;
         }
 
         public  ValueProviderResult GetValue( string  key)
         {
             return  ContainsPrefix(key)
                 ? new  ValueProviderResult(  "这是一个值提供程序示例" , null ,System.Globalization.CultureInfo.InstalledUICulture)
                 : null ;
         }
     }
}

看到代码1-3中MyCustomValueProvider的定义,小伙伴们莫慌待我慢慢解释,首先MyCustomValueProvider类型实现了IValueProvider接口类型,这个是必须的。对于IValueProvider接口类型的定义我就不放代码了,也就是MyCustomValueProvider类型的的两个方法了。

ContainsPrefix()方法的意思是值提供程序内部判断是否含有指定的前缀,把值提供程序想象成一个数据源,这个数据源中包含了键和值,这个ContainsPrefix()方法就是用来判断指定的键是否存在,如果存在的话GetValue()方法则会返回对应的值(在我们的示例中这里的ContainsPrefix()只是作了一逻辑判断,判断当前控制器方法的参数名称【Model名称】是否为ValueProviderCase)。

而GetValue()方法的意思上面也说到了,就是用来返回指定前缀的值(指定键的值),在我们的示例中只是返回了"这是一个值提供程序示例"。有的朋友可能发现了GetValue()方法的返回类型并不是String类型,而是ValueProviderResult类型,这是MVC框架干的好事,也就是它要我们强制的封装我们的返回值,没办法受制于人封装就封装吧,小伙伴们看一下ValueProviderResult类型的定义:

代码1-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public  class  ValueProviderResult
     {
         protected  ValueProviderResult();
         public  ValueProviderResult( object  rawValue,  string  attemptedValue, CultureInfo culture);
         public  string  AttemptedValue {  get protected  set ; }
         public  CultureInfo Culture {  get protected  set ; }
         //
         // 摘要:
         //     获取或设置值提供程序所提供的原始值。
         //
         // 返回结果:
         //     原始值。
         public  object  RawValue {  get protected  set ; }
         public  object  ConvertTo(Type type);
         public  virtual  object  ConvertTo(Type type, CultureInfo culture);
     }

看到代码1-4中的ValueProviderResult类型的构造函数定义和RawValue属性的注释了吧,然后再看一下代码1-3中GetValue()方法的代码定义,一目了然吧。

 

4.自定义值提供程序工厂定义

切回主要流程,我们在使用Model绑定器中的自定义值提供程序的同时,我们也要回想一下上一个篇幅中所讲的就是自定义值提供程序的由来,自定义值提供程序是由我们自定义值提供程序工厂生成的,然后把这个工厂注册到系统的ValueProviderFactories. Factories中,然后会在Model绑定器执行之前生成ModelBindingContext类型实例的时候从ValueProviderFactories. Factories中获取到自定义值提供程序(MyCustomValueProvider类型)赋值到ModelBindingContext类型实例的属性ValueProvider上(对于这里的过程可以观看上一篇)。

现在我们看一下自定义值提供程序工厂定义,代码1-5.

代码1-5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using  System.Web.Mvc;
 
namespace  MvcApplication.ValueProvider
{
     public  class  MyCustomValueProviderFactory:ValueProviderFactory
     {
         public  override  IValueProvider GetValueProvider(ControllerContext controllerContext)
         {
             if  (controllerContext.Controller.GetType().Name ==  "ValueProviderCaseController" )
             {
                 return  new  MyCustomValueProvider();
             }
             return  null ;
         }
     }
}

代码1-5中GetValueProvider()方法被我添加了个逻辑判断,想指示这个工厂只为ValueProviderCaseController控制器服务,这里大家都好理解的就不多说了。

 

5.自定义Model绑定器

再次回到主要流程,上面说过先看Model绑定器执行部分的,现在来看Model绑定器获取部分流程。不多说直接来看自定义Model绑定器的定义,代码1-6.

代码1-6

1
2
3
4
5
6
7
8
9
10
namespace  MvcApplication.Binders
{
     public  class  ValueProviderModelBinder : IModelBinder
     {
         public  object  BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
         {
             return  bindingContext.ValueProvider.GetValue(bindingContext.ModelName).RawValue;
         }
}
}

代码1-6中通过bindingContext中的ValueProvider属性有着对值提供程序的引用,调用了代码1-3中的GetValue()方法,并且把参数名称传递过去进行逻辑判断。最后通过返回值ValueProviderResult类型的RawValue直接返回我们定义的值。

 

6.将我们自定义的"乱七八糟"类型注册到MVC框架中

通过上面那些类型的定义还是不够的,我们还需要将他们注册到系统中,惯例我们在Global.asax文件中添加,当然也可以在控制器激活的过程中进行注册,针对特定的控制器定制特定的Model绑定器,当然了在实际的项目开发实用不实用不清楚,只是这样感觉Global.asax文件中会&ldquo;干净&rdquo;一点。不瞎扯了,来看注册的代码定义1-7.

代码1-7

1
2
ModelBinders.Binders.Add( typeof ( string ),  new  Binders.ValueProviderModelBinder());
ValueProviderFactories.Factories.Insert(0,  new  ValueProvider.MyCustomValueProviderFactory());

将代码1-7添加到Application_Start()方法中,首先是向系统注册了我们自定义的Model绑定器,然后将自定义的值提供程序工厂添加到系统,这里用了Insert()方法来添加,目的是想让我的这个工厂处在默认的之前在第一个的位置,省的再一个个的去判断浪费时间。也可以用Add()方法,只不过是添加到了尾处。

 最后我们看一下结果图:

图2




     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1433767,如需转载请自行联系原作者




相关文章
|
13天前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
50 0
|
13天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
27 0
|
13天前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
34 0
|
13天前
mvc.net分页查询案例——mvc-paper.css
mvc.net分页查询案例——mvc-paper.css
6 0
|
13天前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
125 5
|
13天前
|
XML 前端开发 定位技术
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
35 0
|
13天前
|
前端开发
.net core mvc获取IP地址和IP所在地(其实是百度的)
.net core mvc获取IP地址和IP所在地(其实是百度的)
128 0