Web Api 中Get 和 Post 请求的多种情况分析
转自:http://www.cnblogs.com/babycool/p/3922738.html
来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理。
这里我使用Jquery 来发起异步请求实现数据调用。
继续使用上一文章中的示例,添加一个index.html页面,添加对jquery的引用。

一、无参数Get请求
一般的get请求我们可以使用jquery提供的$.get() 或者$.ajax({type:"get"}) 来实现:

请求的后台Action方法仍为上篇文章中的GetUser() :

也可以用$.ajax({type:"get"}) 方式,正确的获得了返回数据:

二、传递一个参数的Get请求
通常我们需要传递参数只需要指定ajax方法的data属性即可: data:{"name":"赵大宝"}

后台正确的返回数据:

三、传递两个或多个参数的Get请求
按照上面的方法,对于多个参数我们可以很容易就写出来: data:{"name":"赵大宝","age":12}

后台正确的返回数据:

四、无参数的Post请求
我们可以使用$.post() 或$.ajax({type:"post"}) 来发起post请求:

后台正确的返回了数据:

五、传递一个参数的Post请求:
首先这里需要提醒大家一下,我们在修改完后台代码后,如果没有重新生成项目,那么在请求时就会报错:“未找到与请求***匹配的HTTP资源” :

所以,我们只要我们修改了后台代码,就一定要重新生成一下:

不过,当我们重新生成项目,再次发送请求,看到的仍然是404错误,再次检查一番代码,也没有发现是哪里的问题。

事实上,ASP.NET Web API能够正确的识别我们的UserController控制器处理Post /api/user ,但却不能找到一个可以接受的方法来处理请求。
也就是说,Web API接收到的请求能够找到User控制器,但在该控制器中找不到名称为Def 的这个Action。
那我们要怎么来解决呢?
通过搜索MSDN上Web API官网中的说明,我们可以找到下面的一段介绍:

即在Action 方法中我们需要使用 [FromBody] 属性标签来标明属性。
修改后,再次发送请求,我们可以看到,Status Code 为200,请求发送成功。

可以看到,在post请求中,方法的参数必须要用 [FromBody] 属性来修饰才可以, [FromBody] 就告诉Web API 要从post请求体重去获取参数的值。
但让我们诧异的却是,后台返回的数据中name的值为空。

通过调试,我们可以看到,后台Action 中接收到的name值为null。

通过上面的测试我就也能够猜测到,Web API 要求请求传递的 [FromBody] 参数,肯定是有一个特定的格式,才能被正确的获取到。而这种特定的格式并不是我们常见的 key=value 的键值对形式。Web API 的模型绑定器希望找到 [FromBody] 里没有键名的值,也就是说, 不是 key=value ,而是 =value 。
现在,咱们把data中的key设置为空,然后再次发送请求:

测试可见,后台正确的接收到了数据:

六、传递两个参数的Post请求
按理说,一个参数的请求实现了,那么传递两个或者多个参数也就很顺利了,对于两个参数的后台接收方法,我们可能会这样来写:

但事实证明,这样是错误的。

那到底两个或者多个参数我们要怎样来定义呢?
再次查看官网中的介绍,我们了解到:

也就是说,[FromBody] 修饰的参数只能有一个。我们需要对传递的多个参数进行封装才行。
这里,我们可以将 Name和 Age 封装成一个Student 类:

前台页面再次发送请求:

Status Code为200,请求成功,并正确获取到后台返回的数据:

这里,我们通过上面图片中的请求头数据可以看到,Form Data 的格式是 key=value&key=value 这种表单数据格式 Name=%E8%B5%B5%E5%A4%A7%E5%AE%9D&Age=13 ,我们平时使用的比较多的一般为json格式。 这里,我们使用 JSON.stringify() 来序列化数据。

再次发送请求:

可以看到,From Data 中数据的格式为json字符串,Status Code为200,请求正确,但结果又出错了,后台又没有接收到数据参数:

那么问题到底出在哪呢?
我们再次查看上图中请求头内容,注意到,虽然我们传递的数据格式是json字符串,但请求头中的Content-type 却为
application/x-www-form-urlencoded ,并不是json格式对于的 application/json 。 而编码格式 application/x-www-form-urlencoded 表示的是:窗体数据被编码为名称/值对。
这里,也就是我想要说的一个注意点。平时我们在使用json数据的时候,很容易就忘记了 要指定 Content-type 为 "application/json" ,所以就容易导致很多“想不到”的错误。
所以,我们在 $.ajax() 中指定 Content-type :

这次,后台正确的接收并返回了数据:

七、传递多个参数的Post请求
有了上面的经验,传递多个参数的post请求我们就很容易能写出来了:

后台接收并返回数据:

八、传递多个不同对象的Post请求
有时候我们还会遇到需要传递多个不同对象参数的情况,对于这种特殊的情况在 Json.Net 中为我们提供了一个 名为 JObject 的通用对象容器,我们可以通过 .对象名 的方式来动态的遍历参数里面的属性的值,然后动态的转换和json类型中对应的属性类型。
比如:

后台调试,通过dynamic 动态转换获取属性的值:

后台正确的返回了数据:

九、获取不同类型的数据
一般我们获取到后台返回的数据格式类型为 json格式,我们也可以指定 请求头中的输出类型来获得不同的返回类型数据:
指定输出类型为xml格式:

指定输出类型为 json格式:

基本到这里,这篇文章的主要内容也就算说完了,其中的重点还是 Post请求中对于参数的处理是需要重点注意的。
上面我们在测试的过程中,都是通过自己创建的Controller控制器类来对参数进行接收处理,可能有人会问,我们这么写到底是否符合规范呢,Web API中默认是怎么来处理的呢? 这里,Visual Studio 中也为我们自带了 Web API控制器类:
我们可以添加新建项选择 Web API控制器类 即可:


这里我们可以看到,默认创建的Controller控制器类中,对于Post请求的Action方法都自带了 [FromBody] 属性。 现在不用我说,你也已经知道为什么 它会为参数默认带一个 [FromBody]属性吧!
好了,今天的内容就到这里,下面附上我参考的几篇文章:
MSDN中关于Web API 中 [FromBody] 的介绍: Parameter Binding in ASP.NET Web API | The ASP.NET Site
关于[FromBody]属性的介绍及Post参数说明(E文): Using jQuery to POST [FromBody] parameters to Web API | Encosia
上面网页文章的翻译版本:【翻译】使用JQuery POST表单到Web API | 北飘漂
Post 多个参数到Web API的总结: POST多个参数到Web API控制器方法总结 | 北飘漂
附当前项目的代码:XWebAPIDemo-WebAPI请求
转载请注明出处。
Web Api 中Get 和 Post 请求的多种情况分析的更多相关文章
- 关于Web API中使用ajax发送请求方式的问题
参见以下文章 http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API ...
- WEB API 中HTTP的get、post、put,delete 请求方式
一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持, ...
- Web APi 2.0优点和特点?在Web APi中如何启动Session状态?
前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...
- Web Api 中返回JSON的正确做法
在使用Web Api的时候,有时候只想返回JSON:实现这一功能有多种方法,本文提供两种方式,一种传统的,一种作者认为是正确的方法. JSON in Web API – the formatter b ...
- 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化
谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...
随机推荐
- oracle通过sequence定义触发器支持id的自增
sequence:s_author_id,从1开始步幅是1,最大值是999999999 -- Create sequence create sequence S_AUTHOR_ID minvalue ...
- Tomcat在局域网中localhost可以访问,但是无法通过本地ip访问,127.0.0.1也无法访问问题的解决方法
环境:Tomcat6,Windows Server2008 R2, Tomcat使用默认端口8080. 在BO服务器上使用Tomcat6作为WEB服务器,在服务器本地使用http://localhos ...
- BZOJ2164 : 采矿
树链剖分+线段树,每个节点维护以下信息: (1)单独在某个点分配$i$个人的最大收益.可以$O(m)$合并. (2)分配$i$个人的最大收益.可以用$O(m^2)$合并. 时间复杂度$O(c(m^2\ ...
- BZOJ3569 : DZY Loves Chinese II
这回是真·强制在线了,首先这道题就是AHOI2013连通图的加强版,那道题k最大只有4 那道题的做法是: 取一个生成树,对每条非树边取一个随机权值, 对每条树边设为“覆盖它的所有非树边”的权值的xor ...
- (转)HBase工程师线上工作经验总结----HBase常见问题及分析
阅读本文可以带着下面问题:1.HBase遇到问题,可以从几方面解决问题?2.HBase个别请求为什么很慢?你认为是什么原因?3.客户端读写请求为什么大量出错?该从哪方面来分析?4.大量服务端excep ...
- mysql修改默认编码为UTF8
Linux下一般是 /etc/my.cnf --在 [mysqld] 标签下加上三行default-character-set = utf8character_set_server = utf8 -- ...
- ACM: A Simple Problem with Integers 解题报告-线段树
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%lld & %l ...
- NOIp 2013 #3 转圈游戏 Label:模拟
题目描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此 ...
- 【BZOJ】1987: Zju2672 Fibonacci Subsequence
题意 给出一个序列\(A\),求一个最长的满足fib性质的子序列,输出其长度及其元素(如果多种方案,输出位置最靠前的).(\(n \le 3000\)) 题解 容易想到dp,即\(d(i, j)\)表 ...
- 【poj2828】Buy Tickets
Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get ...