Webapi传参数

来源:互联网 发布:软件合同书 编辑:程序博客网 时间:2024/06/18 06:33

一、Get请求

1、传一个基础类型参数

[HttpGet]        public IHttpActionResult TestGetOnePara(string name)        {            return Json<object>(new { ParaVal = name, ParaDes = "Get方法传一个参数" });        }


2、传多个基础参数

HttpGet]        public IHttpActionResult TestGetMorePara(string name,int age)        {            return Json<object>(new { Name = name,Age=age, ParaDes = "Get方法传多个参数" });


3、传实体参数(错误写法)

[HttpGet]        public IHttpActionResult TestGetOneEntity(Person pso)        {            return Json<object>(new { Name = pso.name, Age = pso.age, ParaDes = "Get方法传一个实体参数" });        }


后台为什么会接收不到参数呢?原来,get请求的时候,默认是将参数全部放到了url里面直接以string的形式传递的,后台自然接不到了。
原因分析:还记得有面试题问过get和post请求的区别吗?其中有一个区别就是get请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),而post请求则是放在http协议包的包体中。Get请求的时候可以在参数里面加上[FromUri]即可直接得到对象。还是贴上代码:

[HttpGet]        public IHttpActionResult TestGetOneEntity([FromUri]Person pso)        {            return Json<object>(new { Name = pso.name, Age = pso.age, ParaDes = "Get方法传一个实体参数" });        }


二、post请求
1、传一个基础类型参数(错误写法)

[HttpPost]        public IHttpActionResult TestPostOnePara(string name)        {            return Json<object>(new { ParaVal = name, ParaDes = "Post方法传一个参数" });


为什么会报找不到匹配的方法呢?原来post请求的基础类型的参数和get请求有点不一样,我们知道get请求的参数是通过url来传递的,而post请求则是通过http的请求体中传过来的,WebApi的post请求也需要从http的请求体里面去取参数。我们一般的通过url取参数的机制是键值对,即某一个key等于某一个value,而这里的FromBody和我们一般通过url取参数的机制则不同,它的机制是=value,没有key的概念,并且如果你写了key(比如你的ajax参数写的{NAME:Jim}),后台反而得到的NAME等于null。

2、传一个基础类型参数(正确写法)

[HttpPost]        public IHttpActionResult TestPostOnePara([FromBody]string name)        {            return Json<object>(new { ParaVal = name, ParaDes = "Post方法传一个参数" });


3、传多个基础类型(错误写法)

上面讲的都是传递一个基础类型参数的情况,那么如果我们需要传递多个基础类型呢?按照上面的推论,是否可以([FromBody]string name, [FromBody]string age)这样写呢。试试便知。

[HttpPost]        public IHttpActionResult TestPostMorePara([FromBody]string name,[FromBody]int age)        {            return Json<object>(new { Name = name, Age = age, ParaDes = "Post方法传多个参数" });        }


说明我们没办法通过多个[FromBody]里面取值,此法失败。既然上面的办法行不通,那我们如何传递多个基础类型的数据呢?很多的解决办法是新建一个类去包含传递的参数,博主觉得这样不够灵活,因为如果我们前后台每次传递多个参数的post请求都去新建一个类的话,我们系统到时候会有多少个这种参数类?维护起来那是相当的麻烦的一件事!所以博主觉得使用dynamic是一个很不错的选择。我们来试试。

[HttpPost]        public IHttpActionResult TestPostMorePara(dynamic obj)        {            return Json<object>(new { Name = Convert.ToString(obj.name), Age = Convert.ToString(obj.age), ParaDes = "Post方法传多个参数" });        }


过dynamic动态类型能顺利得到多个参数,省掉了[FromBody]这个累赘,并且ajax参数的传递不用使用无厘头的{:value}这种写法,有一点需要注意的是这里在ajax的请求里面需要加上参数类型为Json,即 contentType: application/json, 这个属性。

4、传实体参数

[HttpPost]        public IHttpActionResult TestPostOneEntity(Person obj)        {            return Json<object>(new { Name = obj.name, Age =obj.age, ParaDes = "Post方法传一个实体参数" });        }


 原理解释:使用实体作为参数的时候,前端直接传递普通json,后台直接使用对应的类型去接收即可,不用FromBody。但是这里需要注意的一点就是,这里不能指定contentType为appplication/json,否则,参数无法传递到后台。我们来看看它默认的contentType是什么:application/x-www-form-urlencoded

为了弄清楚原因,博主查了下http的Content-Type的类型。看到如下说明:
• application/x-www-form-urlencoded :
中默认的encType,form表单数据被编码为keyalue格式发送到服务器(表单默认的提交数据的格式);
• application/json    : JSON数据格式
也就是说post请求默认是将表单里面的数据的keyalue形式发送到服务,而我们的服务器只需要有对应的keyalue属性值的对象就可以接收到。而如果使用application/json,则表示将前端的数据以序列化过的json传递到后端,后端要把它变成实体对象,还需要一个反序列化的过程。按照这个逻辑,那我们如果指定contentType为application/json,然后传递序列化过的对象应该也是可以的啊,如图:


5、数组作为参数

[HttpPost]        public IHttpActionResult TestPostOneEntity(List <Person> obj)        {            //var result = new ResultContainer1<Person>();            //result.Data = obj.ToArray();            return Json<List<Person>>(obj);        }



0 0
原创粉丝点击