ASP.NET Web API Model-ValueProvider

前言

前面一篇讲解了Model元数据,Model元数据是在Model绑定中很重要的一部分,只是Model绑定中涉及的知识点比较多,对于ASP.NET MVC框架来说ASP.NET Web API框架中在Model绑定部分又新增了参数绑定这么一个机制,这些内容都会在后面的篇幅中说明,前面的这些篇幅都是讲解理论上的知识也没有涉及到示例的演示,这个大家不用急在最后Model部分的基础知识讲解完之后我会把前面所讲的全部串联起来,而今天这个篇幅给大家带来的就是在Model绑定中起到至关重要的一个环节,大家这个不用去管什么Model绑定,而是单纯的去了解ValueProvider这一系列的对象模型,因为在没有结合前后知识点串联起来之前,我们都不知道ValueProvider是在哪执行的。所以我们还是老老实实了解一下ValueProvider相关的对象吧。

Model-ValueProvider

图1

IValueProvider接口类型--ValueProvider行为约束

首先我们看一下图1中右边的部分,起头的就是一个IValueProvider接口类型,我们就来看一下接口的定义:

示例代码1-1

    public interface IValueProvider
{
bool ContainsPrefix(string prefix);
ValueProviderResult GetValue(string key);
}

我们在代码1-1中看到,IValueProvider接口中定义了两个方法,一个是ContainsPrefix()方法,接收string类型的参数并且返回的是bool值类型,这个方法表示的就是根据指定的前缀值查看当前的ValueProvider中是否存在这个前缀值,这个下面会有示例稍后再说,然后就是GetValue()方法,是根据执行的键值返回当中的对应的值,从这里一看我们就大概能猜到这个ValueProvider应该是类似于键值队一样的类型,而返回的结果被封装在了ValueProviderResult类型当中,这个类型稍后会有说明。在IValueProvider接口约束好ValueProvider值提供程序的行为后,我们应该就来看一看ValueProvider值提供程序的基础结构了。不过呢在此之前我们还是要根据图1中所示的那样,先来看一下IEnumerableValueProvider接口类型的定义,这个接口主要负责什么呢?

IEnumerableValueProvider接口类型-ValueProvider行为约束

示例代码1-2

    public interface IEnumerableValueProvider : IValueProvider
{
IDictionary<string, string> GetKeysFromPrefix(string prefix);
}

从代码1-2中可以很清楚明了的看到IEnumerableValueProvider接口类型的职责很简单,就是对指定的前缀值进行检索,并且最后以键值队的形式返回,这个在下面会有示例详细说明。

NameValuePairsValueProvider类型-ValueProvider基础结构

示例代码1-3

    public class NameValuePairsValueProvider : IEnumerableValueProvider, IValueProvider
{
public NameValuePairsValueProvider(Func<IEnumerable<KeyValuePair<string, string>>> valuesFactory, CultureInfo culture);
public NameValuePairsValueProvider(IEnumerable<KeyValuePair<string, string>> values, CultureInfo culture); public virtual bool ContainsPrefix(string prefix);
public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix);
public virtual ValueProviderResult GetValue(string key);
}

在代码1-3中我们看到NameValuePairsValueProvider类型的定义,首先就说说它的构造函数吧,两个构造函数的区别在于第一个是Func<IEnumerable<KeyValuePair<string, string>>>类型的构造函数参数,第二个是IEnumerable<KeyValuePair<string, string>>类型的构造函数参数,第二个构造函数的首个参数类型实际就是第一个构造函数首个参数的返回类型,这里大家都看得到,其实在内部实现,也是这样的声明第一个构造函数是没什么的,声明第二个构造函数的时候其实就把参数再次封装为委托。

对于KeyValuePair<T,U>类型可以理解为键值队的子项,在它的类型中只有一个键值对应一个值只有一项就是它本身。

至于剩下的三个方法我们还是靠简单的示例来说明一下。

示例代码1-4

    public class ValueProviderCaseController : ApiController
{
public string Get()
{ KeyValuePair<string,string>[] dictionary=new KeyValuePair<string,string>[]
{
new KeyValuePair<string,string>("EmployeesInfo.Name","Jinyuan"),
new KeyValuePair<string,string>("EmployeesInfo.Age",""),
new KeyValuePair<string,string>("EmployeesInfo.Sex","男"),
new KeyValuePair<string,string>("EmployeesInfo.AddressInfo.AddressInfo","南京市"),
new KeyValuePair<string,string>("EmployeesInfo.AddressInfo.ZipCode","")
};
NameValuePairsValueProvider nameValuePairsValueProvider=new NameValuePairsValueProvider(dictionary,null);
StringBuilder strBuilder = new StringBuilder();
NameValuePairsPrefixAnalysis(strBuilder, nameValuePairsValueProvider, "EmployeesInfo");
return strBuilder.ToString();
} private void NameValuePairsPrefixAnalysis(StringBuilder stringbuilder, NameValuePairsValueProvider namevaluepairs,string prefix)
{
IDictionary<string, string> dictionarys = namevaluepairs.GetKeysFromPrefix(prefix); if (dictionarys.Count > )
{
Console.WriteLine(prefix + "为前缀的数据源Key值检索……");
foreach (var item in dictionarys)
{
Console.WriteLine("Key:" + item.Key + " Value:" + item.Value);
}
foreach (KeyValuePair<string, string> keyvalue in dictionarys)
{
NameValuePairsPrefixAnalysis(stringbuilder, namevaluepairs, keyvalue.Value);
}
}
else
{
stringbuilder.AppendLine(prefix+":"+ namevaluepairs.GetValue(prefix).RawValue.ToString());
}
}
}

我们来看代码1-4,首先我在Get()方法中定义了一个KeyValuePair<string,string>[]类型,为了能够实例化NameValuePairsValueProvider类型,在此之后大家可以看到我调用了一个我自定义的NameValuePairsPrefixAnalysis()方法,并且在其中使用NameValuePairsValueProvider类型的实例调用了GetKeysFromPrefix()方法,也就是代码1-2所约束的那个行为。这个时候我们先来看一下表1.

表1

Key

Value

EmployeesInfo.Name

Jinyuan

EmployeesInfo.Age

24

EmployeesInfo.Sex

男

EmployeesInfo.AddressInfo.AddressInfo

南京市

EmployeesInfo.AddressInfo.ZipCode

210000

表1所表示的就是初始数据源,也就是我们定义的KeyValuePair<string,string>[]类型的键、值示意表。

然而在我们使用NameValuePairsValueProvider类型的实例已” EmployeesInfo”作为前缀调用了GetKeysFromPrefix()方法后返回的IDictionary<string, string>类型的值如表2.

表2

Key

Value

Name

EmployeesInfo.Name

Age

EmployeesInfo.Age

Sex

EmployeesInfo.Sex

AddressInfo

EmployeesInfo.AddressInfo

这里的表2值只是第一层的关系值。

在此之后我们输出的当前的所要检索的前缀值以及检索过后的值,并且会遍历表2里的Value值作为前缀值再次的对数据源进行前缀检索,如果没有了则说明已经没有可检索的了。

并且使用NameValuePairsValueProvider类型实例调用的GetValue()方法根据最后已经检索不出来有后缀的前缀值,也就是原始数据源当中的Key值了。

最后我们看一下结果。

图2

在客户端我们获取到了值,当然这里只是演示示例,值提供程序提供的值方向反了。

然后我们可以在服务端看到检索的记录,可以明确的看到有两层的结构在其中。有兴趣的朋友深入一下看下检索的具体实现方式。

QueryStringValueProvider类型-ValueProvider特定结构

示例代码1-5

    public class QueryStringValueProvider : NameValuePairsValueProvider
{
public QueryStringValueProvider(HttpActionContext actionContext, CultureInfo culture)
: base(func, culture)
{
Func<IEnumerable<KeyValuePair<string, string>>> func = null;
if (func == null)
{
func = () => actionContext.ControllerContext.Request.GetQueryNameValuePairs();
}
}
}

从代码1-5中可以看到在QueryStringValueProvider类型初始化的时候构造函数中的执行,把从请求查询字符串作为原始数据来源封装为委托类型,然后调用基类的构造函数。

RouteDataValueProvider类型-ValueProvider特定结构

示例代码1-6

    public class RouteDataValueProvider : NameValuePairsValueProvider
{
public RouteDataValueProvider(HttpActionContext actionContext, CultureInfo culture)
: base(func, culture)
{
Func<IEnumerable<KeyValuePair<string, string>>> func = null;
if (func == null)
{
func = () => GetRoutes(actionContext.ControllerContext.RouteData);
}
}
}

同上面1-5一样的道理,这里使用了HttpRouteData中的Values值作为原始数据源。

还有图1中的左边部分会在后面的篇幅中讲解,在这里讲不适合,会感觉不连贯,虽然看完本篇不知道这个起到了什么作用也不知道怎么去使用,感觉被掐住了脖子一样的难受,但是后面我会把前面所讲的内容全部串联起来做一个演示,所示这是基础部分的知识,就是一个铺垫。

作者:金源

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

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

ASP.NET Web API Model-ValueProvider的更多相关文章

  1. Model Validation in ASP.NET Web API

    Model Validation in ASP.NET Web API 原文:http://www.asp.net/web-api/overview/formats-and-model-binding ...

  2. Asp.Net Web API 2第十五课——Model Validation(模型验证)

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文参考链接文章地址htt ...

  3. ASP.NET Web API Model-ModelBinder

    ASP.NET Web API Model-ModelBinder 前言 本篇中会为大家介绍在ASP.NET Web API中ModelBinder的绑定原理以及涉及到的一些对象模型,还有简单的Mod ...

  4. 新作《ASP.NET Web API 2框架揭秘》正式出版

    我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西.对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠.如果我们将整个“ ...

  5. ASP.NET Web API 2框架揭秘

    ASP.NET Web API 2框架揭秘(.NET领域再现力作顶级专家精讲微软全新轻量级通信平台) 蒋金楠 著   ISBN 978-7-121-23536-8 2014年7月出版 定价:108.0 ...

  6. 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. 本文主要来讲解以下内容: ...

  7. ASP.NET Web API中的参数绑定总结

    ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...

  8. Parameter Binding in ASP.NET Web API(参数绑定)

    Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...

  9. 《ASP.NET Web API 2框架揭秘》

    <ASP.NET Web API 2框架揭秘> 基本信息 作者: 蒋金楠 出版社:电子工业出版社 ISBN:9787121235368 上架时间:2014-7-5 出版日期:2014 年7 ...

随机推荐

  1. JavaWeb——Filter

    一.基本概念 之前我们用一篇博文介绍了Servlet相关的知识,有了那篇博文的知识积淀,今天我们学习Filter将会非常轻松,因为Filter有很多地方和Servlet类似,下面在讲Filter的时候 ...

  2. Kali对wifi的破解记录

    好记性不如烂笔头,记录一下. 我是在淘宝买的拓实N87,Kali可以识别,还行. 操作系统:Kali 开始吧. 查看一下网卡的接口.命令如下 airmon-ng 可以看出接口名称是wlan0mon. ...

  3. MIP开发常见问题解答

    校验相关 1. MIP 页面的 <a>链接校验报错,MIP 是强制 target="_blank" 吗? 如果想直接跳转MIP页,可以用mip-link 组件:MIP ...

  4. C# - 值类型、引用类型&走出误区,容易错误的说法

    1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...

  5. Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用

    OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...

  6. [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密

    string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...

  7. 【原创分享·微信支付】 C# MVC 微信支付教程系列之扫码支付

    微信支付教程系列之扫码支付                  今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添 ...

  8. potrace源码分析一

    1 简介 potrace是由Dalhousie University的Peter Selinger开发一款位图轮廓矢量化软件,该软件源码是可以公开下载的,详细见项目主页:http://potrace. ...

  9. EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因(系列4)

    前言 Entity Framework 延伸系列目录 今天我们来聊聊EF的日志记录. 一个好的数据库操作记录不仅仅可以帮你记录用户的操作, 更应该可以帮助你获得效率低下的语句来帮你提高运行效率 废话不 ...

  10. C# 索引器,实现IEnumerable接口的GetEnumerator()方法

    当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...