Asp.Net Core Web Api 路由传参探幽
声明
0.本人的结论都是经过测试得出的,某些情况会可能会忽略而导致结论错误,请指正!
1.关于模型绑定(将HTTP请求中各种可能的参数映射到接口中的简单类型或者复杂类型)的相关问题可以查看我的另外一篇博客,或者去微软官网 模型绑定 模型绑定官网
2.在模型绑定这篇文章中主要是讲如何将一个类型映射到另外的一个类中。
2.1 简单类型-简单类型 int-int string-string
2.2 简单类型-复杂类型(string,int,bool)-class
2.3 Json-简单类型
2.4 Json-复杂类型
3.而本文主要探讨在传参时的一些特殊情况,用不同的方式传参有什么区别,接收时要注意什么
不同的方式传参
本文需要用到的自定义复杂类型:
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public string Color { get; set; }
}
query传参
1.简单类型-简单类型
[HttpGet]
public ActionResult Get(string a, int b);
http://localhost:5000/api/values?a=aaa&b=111
2.简单类型-复杂类型
[HttpGet]
public ActionResult Get(Student student);
http://localhost:5000/api/values?age=11&name=jack&color=red
3.Json-简单类型,复杂类型
query没必要用json来传递简单类型
query无法将Json格式的字符串直接映射到复杂类型,可能是复杂类型会忽略其名称(student)。但是可以传递Json格式的字符串至一个字符串接收器,随后可以二次解析。
总结:query只能传递简单类型,而接受方则可以是简单类型和复杂类型
Route传参
1.路由也只能传递简单数据类型(路由本身不可能是复杂类型)
2.不是路由中的任何值都能做参数
[HttpGet("id")]
public ActionResult Get(int id);
http://localhost:5000/api/values/id?id=5
此时,路由中的第一个id并没有做参数,而是单纯的路由,且不可以被省略,否则会找不到路由
3.将路由当做参数
[HttpGet("{id}")]
public ActionResult Get(int id)
http://localhost:5000/api/values/6
将路由中id加上{}后就能将id当做参数了。即使后面再跟别的query id,后面的id也不会起作用了。
如果将路由中6改成字符串,则id的值为默认的0
4.可以指定多级路由来传递至复杂类型
[HttpGet("{Age?}/{Name?}/{Color?}")]
public ActionResult Get(int Age, Student student)
http://localhost:5000/api/values/8/shang/red
总结:route只能传递简单类型,而接受方则可以是简单类型和复杂类型
Header传参
header出传参必须加[FromHeader],否则无法识别
1.简单类型-简单类型
[HttpGet()]
public ActionResult Get([FromHeader]int age, [FromHeader]string name, [FromHeader]string color)
http://localhost:5000/api/values/
2.简单类型-复杂类型
[HttpGet()]
public ActionResult Get([FromHeader]Student student)
注意:无法通过简单类型传递到复杂类型
3.Header传递的Json字符串无法被识别
总结:header只能传递简单类型,而接受方则也只能是简单类型
From传参
1.简单类型-简单类型
[HttpGet()]
public ActionResult Get([FromHeader]int age, [FromHeader]string name, [FromHeader]string color)
http://localhost:5000/api/values/
2.简单类型-复杂类型
[HttpGet()]
public ActionResult Get(Student student)
http://localhost:5000/api/values/
3.无法用json传递
4.传文件
看我写的模型绑定那篇文章
总结:form只能传递简单类型,而接受方则可以是简单类型和复杂类型
Body传参
1.Body传参也必须加上[FromBody]属性,否则无法识别
2.asp.net core默认接收json格式的数据,除非设置了其他格式的解析,本文只采用json来传参。想要添加xml格式的解析,或者添加自定义解析可以看官方文档。
3.Body不存在简单类型和复杂类型,就是Json格式
4.一个参数列表只能存在一个[FromBody]
5.json-简单类型
[HttpGet()]
public ActionResult Get([FromBody]string name)
body无法传递简单数据
6.json-复杂类型
[HttpGet()]
public ActionResult Get([FromBody]Student student);
http://localhost:5000/api/values/
总结:body只能传递json字符串,而接受方只能是复杂类型
同时指定参数
如果这几种传参方式同时指定了值,那么会选择谁呢?
由于header和body都需要指定[FromXXX]属性,所以不需要考虑了。
测试结果:
1.当form,query,route同时指定时,选择form
http://localhost:5000/api/values/route?name=query
2.当query,route同时指定时,选择route
http://localhost:5000/api/values/route?name=query
默认值
值类型
1.不传值
[HttpGet()]
public ActionResult Get(int a, bool b, DateTime c);
http://localhost:5000/api/values/
结果:
2.传匹配类型的值
[HttpGet()]
public ActionResult Get(int a, bool b, DateTime c);
http://localhost:5000/api/values?a=11&b=true&c=1992-01-02
结果:
3.传不匹配类型的值
[HttpGet()]
public ActionResult Get(int a, bool b, DateTime c);
http://localhost:5000/api/values?a=11&b=name&c=19920102
结果:
总结:值类型如果不传值或者传不匹配的值,则值为该类型的默认值。传匹配的值则正确接收值
引用类型
1.不传值
[HttpGet()]
public ActionResult Get(Student student,string other);
http://localhost:5000/api/values
结果:
2.传配类型的数据
[HttpGet()]
public ActionResult Get(Student student,string other);
http://localhost:5000/api/values?age=11&name=zhang&color=red&other=sui
结果:
3.引用类型不存在不匹配的数据
总结:string类型的数据不传值则为null,传值则为该值。复杂类型本身不为null(实际上asp.net core会在内部调用它的默认构造函数),但是它包含的属性(值类型,引用类型)都遵循前述规则
由服务端接收到的值推断客户端的传参形式
值类型
1.服务端接收到的值为除默认值外的值
客户端传值了
2.服务端接收到了默认值
客户端没传值,客户端传了个不符合类型的值,客户端传了默认值
解决办法:
客户端没传值:用可空类型约束
客户端传了不符合类型的值:校验ModelState
客户端传了默认值:正确,不用做
总结:要根据服务端接收到的值推断客户端的具体行为采用的方法是可空类型+ModelState。可以判断客户端想要将值设为另外一个值还是不改动(为null则不改动,为数值类型包括默认值则就为该值)
引用类型
1.服务端接到的值不为null
客户端传了正确的值
2.服务端接收到的值为null
客户端没传值,客户端传了空白
http://localhost:5000/api/values
http://localhost:5000/api/values?name=
http://localhost:5000/api/values?name=空格
解决办法
设置默认值
总结:当一个引用类型无法判断是想修改值还是不修改值时,可以用设置默认值的方式,接收到默认值,说明是不修改值,接收null则表示将值改为null。
上一篇: python切割图片
下一篇: c#高效比对大量图片的实例代码