ASP.NET MVC Web API Post FromBody(Web API 如何正确 Post)
问题场景:
ASP.NET MVC Web API 定义 Post 方法,HttpClient 使用 JsonConvert.SerializeObject 传参进行调用,比如 Web Api 中定义 AddProduct 方法,参数为 Product 的各类信息(id、name等),然后操作完之后返回处理信息。
问题分析:
曾经在之前写过一篇 Web API 的博文《初试ASP.NET Web API/MVC API(附Demo)》,但只是讲解了 Get 的用法,因为比较简单,通过 URL 就可以进行传参,比如 URL:http://localhost:9283/api/product/get/1 ,这个就表示在控制器 Product 中获取 ID 为 1 的 Product,客户端不需要配置什么,直接在 HttpClient 中传入这个 URL 就可以了。
Web API 中使用 Post 的方式可以参考《HttpClient + ASP.NET Web API, WCF之外的另一个选择》,我按照文中的方式试了下,代码如下:
ProductController 代码:
public class ProductController : ApiController
{
[HttpPost]
public int AddProduct(string id, string name)
{
return 1;
}
}
HttpClient 测试调用代码:
[Fact]
public void WebApiTest_AddProduct()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:1661/");
var requestJson = JsonConvert.SerializeObject(
new
{
id = "1",
name = "2"
});
HttpContent httpContent = new StringContent(requestJson);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = client.PostAsync("api/Product/AddProduct", httpContent).Result.Content.ReadAsStringAsync().Result;
}
}
MapHttpRoute 路由配置:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
异常信息:
![](http://images0.cnblogs.com/blog/435188/201408/151603087959340.png)
看起来似乎没什么问题,但为什么会抱“在控制器“Product”上找不到与该请求匹配的操作。”错误呢?从异常信息可以看出,应该是路由问题,也就是说找不到 Action-AddProduct,但是写的路由配置没什么问题啊(我自己认为),然后网上各种关键字搜索,找了很多资料,我也试了很多方式,因为对 WEB API 的路由配置不是很熟悉,然后新建 Demo,一点一点的进行测试,发现几个点,比如路由默认配置是没有 {action} 的,还有就是上面测试代码中 PostAsync,默认不知道为什么会当作 Get 使用,比如我们在 AddProduct 方法中去掉一个 name 参数,这时候我们测试会发现是执行 AddProduct,但是参数 id 变成了“AddProduct”,显然 action 的名字当作了 id 的值,这个我觉得有两个原因,一个是我路由配置没有配置好,还有就是测试客户端的代码写的有问题,因为急着解决这个问题,所以也没有研究这其中的原因,最后发现了 FromBody(只能标识一个),我之前在找问题的过程中,也是使用过它,但是当时并没有成功,现在也忘了当时的代码是怎么写的了。
记录一下 Post 可以运行的方式。
ProductController 代码:
public class ProductController : ApiController
{
[HttpPost]
public int AddProduct([FromBody] Product product)
{
return 1;
}
public class Product
{
public string id { get; set; }
public string name { get; set; }
}
}
测试代码和路由配置没有变化,测试结果:
![](http://images0.cnblogs.com/blog/435188/201408/151756428423537.png)
就记录到这里。
相关文章
- [日常] 使用TCPDUMP和Ethereal抓包分析HTTP请求中的异常情况
- [PHP] 解决chrome新版same-site策略跨域无法记录cookie
- [labuladong算法小抄]如何k个一组反转链表
- [视频教程] 基于redis的消息队列实现与思考
- [labuladong算法小抄]递归反转链表一部分
- [日常] 项目中业务绑定手机验证手机号的实现
- [视频教程] 使用docker的方式安装redis
- [日常] Redis中set集合的使用思考
- [日常] 跨语言的POST请求问题的解决
- [labuladong算法小抄]二分查找详解
- [PHP] 基于redis的分布式锁防止高并发重复请求
- [日常] 安装windows+deepin双系统
- [MySQL] 数据库自增ID用完了会怎么样
- [视频教程]利用SSH隧道进行远程腾讯云服务器项目xdebug调试
- [日常] 当前项目前端版本管理的情况
- [计组]数据的存储和排列
- [计组]强制类型转换
- [PHP] vscode配置SFTP扩展同步文件
- [PHP] PHP-FPM的access日志error日志和slow日志
- [计组]移位运算