ASP.NET WebAPI 04 Model绑定
在前面的几篇文章中我们都是采用在URI中元数据类型进行传参,实际上ASP.NET Web API也提供了对URI进行复杂参数的绑定方式--Model绑定。这里的Model可以简单的理解为目标Anction方法的某个参数。
eg:
public Figure GetFigureFromQueryString([ModelBinder]Figure figure)
{
return figure;
}
请求url: http://localhost:4044/api/Figure/GetFigureFromQueryString?FirstName=Bran&LastName=Stack
结果:
{
"FirstName": "Bran",
"LastName": "Stack"
}
(本篇为了更好的体现绑定结果,所有Anction的返回结果都是请求参数或整合的后的请求参数)
ModelBinder
在之前的文章中多次提到URI的数据主要来源于两种方式:Route,QueryString。但是URI只提供简单的基础数据类型,在上面的例中,我们会发现参数变成了类。ModelBinderAttribute提供了基础数据类型向复杂类型数据转换的功能。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
public class ModelBinderAttribute : ParameterBindingAttribute
{
}
从定义中我们可以看出ModelBinder的AttributeUsage可以看出来ModelBinder可以用于类型与参数。下面我就列举一些Model绑定的形式。
- 简单类
这里所说的简单类是指数据是指类的公开属性是基础数据类型。比如我们之前一直使用的Figure类。
public class Figure
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
还是以本文开始的GetFigureFromQueryString([ModelBinder]Figure figure) 为例。因为该Action中只采用了一个参数。所以在传参的过程中只需要将FirstName,LastName作为QueryString传递,ModelBinder将转换出Figure对象。
http://localhost:4044/api/Figure/GetFigureFromQueryString?FirstName=Bran&LastName=Stack
同时我们也可以采用route形式进行传参:
[Route("GetFigureFromRoute/{FirstName}/{LastName}")]
public Figure GetFigureFromRoute(Figure figure)
url:
http://localhost:4044/api/Figure/GetFigureFromRoute/Bran/Stack
当然以此类推也也可以进行混合的传参:
还是基于 GetFigureFromRoute Action
我们用以下url进行访问:
http://localhost:4044/api/Figure/GetFigureFromRoute/Bran/Stack?FirstName=Robb
那我们得到的结果将是:
{
"FirstName": "Robb",
"LastName": "Stack"
}
由此可以看出
QueryString参数的优先级是高于Route参数的
2.多参数(简单类)
第一种情况我们是考虑了一个参数,现在我们把参数变成两个,如下:
List<Figure> 方法名 (Figure a, Figure b)
因为这个时候出现了两个类型相同的参数,仅靠属性名已经不能对参数进行区别。这个时候WebAPI为我们提供了前缀形式对参数进行区分。下面就以Route的方式做一demo:、
[Route("GetTwoFigureFromRoute/{a.FirstName}/{a.LastName}/{b.FirstName}/{b.LastName}")]
public List<Figure> GetTwoFigureFromRoute(Figure a, Figure b)
我们对路由进行一个简单分析:即{参数名}.{属性名} 作为路由的key
{a.FirstName}:参数a的FirstName属性
{a.LastName}:参数a的LastName属性
{b.FirstName}:参数b的FirstName属性
{b.LastName}:参数b的LastName属性
用以下url访问
http://localhost:4044/api/Figure/GetTwoFigureFromRoute/Bran/Stack/Robb/Stack
得到的结果就是:
[
{
"FirstName": "Bran",
"LastName": "Stack"
},
{
"FirstName": "Robb",
"LastName": "Stack"
}
]
对于QueryString形式传参也非常简单,直接将{参数名}.{属性名} 作为QueryString的key.比如:
public List<Figure> GetTwoFigureFromQueryString(Figure a, Figure b)
url:
http://localhost:4044/api/Figure/GetTwoFigureFromQueryString?a.FirstName=Bran&a.LastName=Stack&b.FirstName=Robb&b.LastName=Stack
将得到如Route形式一样的结果
3.复杂类
现在我们对Figure添加一个Direwolf类的属性Direwolf,让其变为一个复杂类
public class Figure
{
public Direwolf Direwolf { get; set; }
}
public class Direwolf
{
public string Name { get; set; }
public string Color { get; set; }
}
在传参数的过程中显然我们不能对直接对Direwolf属性赋值,所以我们要对Direwolf属性进行拆分,这个时候我也要用到前缀的方式进行传参。如下:
public Figure GetComplexFigureFromQueryString(Figure figure)
url:
http://localhost:4044/api/Figure/GetComplexFigureFromQueryString?FirstName=Jon&LastName=Snow&Direwolf.Color=White&Direwolf.Name=Summer
结果:
{
"FirstName": "Bran",
"LastName": "Stack",
"Direwolf": {
"Name": "Summer",
"Color": "White"
}
}
对于Route形式也是一样:
[Route("GetComplexFigureFromRoute/{FirstName}/{LastName}/{Direwolf.Name}/{Direwolf.Color}")]
public Figure GetComplexFigureFromRoute(Figure figure)
url:
http://localhost:4044/api/Figure/GetComplexFigureFromRoute/Bran/Stack/Grey/Summer
对于多参数的形式也照样可以处理:
public List<Figure> GetTwoComplexFigureFromQueryString(Figure a, Figure b)
url:
http://localhost:4044/api/Figure/GetTwoComplexFigureFromQueryString?a.FirstName=Bran&a.LastName=Stack&a.Direwolf.Color=Grey&a.Direwolf.Name=Summer&b.FirstName=Jon&b.LastName=Snow&b.Direwolf.Color=White&b.Direwolf.Name=Ghost
4.集合类型
集合类型因为存在长度的确定性,所以还是需要通过前缀的方式去指定序列号,如下:
public List<int> GetList([ModelBinder] List<int> list)
{
return list;
}
url:
http://localhost:4044/api/Figure/GetList?[0]=0&[1]=1&[2]=2&[3]=3
结果:
[
0,
1,
2,
3
]
注意
序列号必须是从0开始连续的整数,不然就只能得到序列号断裂之前的数据,如:
url:
http://localhost:4044/api/Figure/GetList?[0]=0&[2]=1&[2]=2&[3]=3
结果:
[
0
]
另外,如果要采用Route形式的传参方式,就必须考虑数据的长度问题。
5字典类型
WebAPI在数据字典类型的先将数据转化成KeyValuePair的集合类型,再转化成字典类型。所以再传参的时候我们可以采用与集合类型一致的方式。如:
public Dictionary<string, int> GetDictionary([ModelBinder]Dictionary<string, int> dic)
url:
http://localhost:4044/api/Figure/GetDictionary?[0].Key=a&[0].Value=1&[1].Key=b&[1].Value=2
结果
{
"a": 1,
"b": 2
}
源码
Github: https://github.com/BarlowDu/WebAPI (API_4)
ASP.NET WebAPI 04 Model绑定的更多相关文章
- ASP.NET WebAPI 05 参数绑定
ParameterBindingAttribute 在上一篇中重点讲了ModelBinderAttribute的使用场景.这一篇详细的讲一下ModelBinder背后的参数绑定原理. ModelBin ...
- ModelBinder——ASP.NET MVC Model绑定的核心
ModelBinder——ASP.NET MVC Model绑定的核心 Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数.通过前面的介绍我们知道Action方法的参数通过 ...
- ASP.NET MVC Model绑定(六)
ASP.NET MVC Model绑定(六) 前言 前面的篇幅对于IValueProvider的使用做个基础的示例讲解,但是没并没有对 IValueProvider类型的实现做详细的介绍,然而MVC框 ...
- ASP.NET MVC Model绑定(五)
ASP.NET MVC Model绑定(五) 前言 前面的篇幅对于IValueProvider的获取位置和所处的生成过程做了讲解,本篇将会对IValueProvider的使用做个基础的示例讲解,读完本 ...
- ASP.NET MVC Model绑定(四)
ASP.NET MVC Model绑定(四) 前言 前面的篇幅对于Model绑定器IModelBinder以及实现类型.Model绑定器提供程序都作了粗略的讲解,可以把Model绑定器想象成一个大的容 ...
- ASP.NET MVC Model绑定(三)
ASP.NET MVC Model绑定(三) 前言 看过前两篇的朋友想必对Model绑定有个大概的了解,然而MVC框架给我们提供了更高的可扩展性的提供程序编程模式,也就是本篇的主题了,会讲解一下Mod ...
- ASP.NET MVC Model绑定(二)
ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...
- ASP.NET MVC Model绑定(一)
ASP.NET MVC Model绑定(一) 前言 ModelMetadata系列的结束了,从本篇开始就进入Model绑定部分了,这个系列阅读过后你会对Model绑定有个比较清楚的了解, 本篇对于Mo ...
- Asp.net MVC中提交集合对象,实现Model绑定
Asp.net MVC中的Model自动绑定功能,方便了我们对于request中的数据的处理, 从客户端的请求数据,自动地以Action方法参数的形式呈现.有时候我们的Action方法中想要接收数组类 ...
随机推荐
- P2207 Photo
P2207 Photo 题目描述 Framer Jhon 打算给他的N头奶牛照相,( 2 <= N <= 1 000 000 000) . 他们排成一条线,并且依次取1~N作为编号. 每一 ...
- 编译的java工程压缩上传到linux服务器上后,中文的类名显示乱码
首先声明,类名是用中文命名的,这个别人写的,不允许修改. 本地用7zip软件压缩成zip包,传到服务器解压,发现中文的class文件名称是乱码. 解决办法: 方法一:使用jar命令打成jar包,传到服 ...
- COGS 栅格网络流
750. 栅格网络流 http://www.cogs.pro/cogs/problem/problem.php?pid=750 ★★☆ 输入文件:flowa.in 输出文件:flowa.out ...
- Linux6.x修改出eth0网卡的解决方法
1. 编辑70-persistent-net配置文件: # -persistent-net.rules 如果没有就新建一个,添加如下内容: # PCI device 0x14e4:0x165f (tg ...
- 《PHP和MySQL Web开发》读书笔记(上篇)
最近过得太浮躁了,实在自己都看不下去了,看了PHP圣经之后,觉得非常有必要要总结一下. Chapter1.快速入门 ·PHP标记:总共有三种风格,常用的还是XML风格为主 <?php echo ...
- FPGA基础知识8(FPGA静态时序分析)
任何学FPGA的人都跑不掉的一个问题就是进行静态时序分析.静态时序分析的公式,老实说很晦涩,而且总能看到不同的版本,内容又不那么一致,为了彻底解决这个问题,我研究了一天,终于找到了一种很简单的解读办法 ...
- Linux查看日志三种命令
第一种:查看实时变化的日志(比较吃内存) 最常用的: tail -f filename (默认最后10行,相当于增加参数 -n 10) Ctrl+c 是退出tail命令 其他情况: tail -n ...
- git之存储(git stash)-------(二)
关于git stash命令的使用方法网上一大把,我想记录的是我在使用过程中觉得实用及好用的: 当在一个分支的开发工作未完成,却又要切换到另外一个分支进行开发的时候,可以先将自己写好的代码,储存在一个箱 ...
- Inline函数使用注意事项
Inline函数使用注意事项 1.在一个文件中定义的inline函数不能再另一个文件中使用 2.inline函数应简洁,只有少数几个语句. 3.在inline函数中不能有循环,if,switch语句. ...
- Spring编程式和声明式事务实例讲解
Java面试通关手册(Java学习指南):https://github.com/Snailclimb/Java_Guide 历史回顾: 可能是最漂亮的Spring事务管理详解 Spring事务管理 S ...