WebAPI接收JSON参数注意事项
运行环境:ASP.NET 4.5.2。
当我们向GlobalConfiguration.Configuration.MessageHandlers添加一个DelegatingHandler派生类后,很容易发生即使命中了Action,但方法参数值为null的问题。
在大多数情况下,我们会在DelegatingHandler派生类里,重写async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)方法。
在方法内,做一些事情,比如说访问日志记录,任意校验,添加Header,修改URL(重写)等工作。
其中最重要需要注意的一点在于request.Content,当我们在方法内访问了request.Content (get)之后,而不对request.Content进行赋值(set)的话,会发生什么呢?
这会导致我们的方法(action)无法获取到客户端Post上来的数据,导致方法参数值为null。
这是为什么呢,这个中原因,我没去深究。
现在附上解决代码:
public class DefaultHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.RequestUri = new Uri(request.RequestUri.ToString()); MediaTypeHeaderValue contentType = request.Content.Headers.ContentType; if (contentType != null)
{
switch (contentType.MediaType)
{
case "application/x-www-form-urlencoded":
{
NameValueCollection formData = await request.Content.ReadAsFormDataAsync(cancellationToken);
request.Content = new FormUrlEncodedContent(Correct(formData));
//TODO:在这里对formData进行业务处理
}
break;
case "multipart/form-data":
{
NameValueCollection formData = await request.Content.ReadAsFormDataAsync(cancellationToken);
request.Content = new FormUrlEncodedContent(Correct(formData));
//TODO:在这里对formData进行业务处理
}
break;
case "application/json":
{
HttpContentHeaders oldHeaders = request.Content.Headers;
string formData = await request.Content.ReadAsStringAsync();
request.Content = new StringContent(formData);
ReplaceHeaders(request.Content.Headers, oldHeaders);
//TODO:在这里对formData进行业务处理
}
break;
default:
throw new Exception("Implement It!");
}
} return await base.SendAsync(request, cancellationToken);
} private static IEnumerable<KeyValuePair<string, string>> Correct(NameValueCollection formData)
{
return formData.Keys.Cast<string>().Select(key => new KeyValuePair<string, string>(key, formData[key])).ToList();
} private static void ReplaceHeaders(HttpHeaders currentHeaders, HttpHeaders oldHeaders)
{
currentHeaders.Clear();
foreach (var item in oldHeaders)
currentHeaders.Add(item.Key, item.Value);
}
}
在Global.asax添加代码:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configuration.MessageHandlers.Add(new DefaultHandler());
}
模型类:
public class TestModel
{
[JsonProperty(PropertyName ="I")]
public long Id { get; set; } [JsonProperty(PropertyName = "N")]
public string Name { get; set; } [JsonProperty(PropertyName = "M")]
public decimal Money { get; set; } [JsonProperty(PropertyName = "IE")]
public bool IsEnable { get; set; } [JsonProperty(PropertyName = "CD")]
public DateTime CreateDate { get; set; } [JsonProperty(PropertyName = "UD")]
public DateTime? UpdateDate { get; set; }
}
ApiController:
public class DefaultController : ApiController
{
[HttpPost]
public TestModel Find(TestModel model)
{
return model;
}
}
Request Body:
{"I":10000,"N":"TestModel","M":21547855.0001,"IE":true,"CD":"2015-12-10 12:12:12","UD":"2016-01-01 01:01:01"}
Fiddler4测试:

测试结果:


解决办法来自:http://stackoverflow.com/questions/27333419/modify-request-content-in-webapi-delegatinghandler
WebAPI接收JSON参数注意事项的更多相关文章
- WebApi传递JSON参数
开发过程中经常进行JSON的传递,在WebApi中传递JSON字串时,会发现服务器端接收到不参数值,看下面代码 服务端: public void Post([FromBody]string value ...
- SpringBoot配置Swagger实例(POST接收json参数)
工程目录结构: 首先,引入jar包,只需要以下两个即可 <dependency> <groupId>io.springfox</groupId> <artif ...
- SpringBoot:自定义注解实现后台接收Json参数
0.需求 在实际的开发过程中,服务间调用一般使用Json传参的模式,SpringBoot项目无法使用@RequestParam接收Json传参 只有@RequestBody支持Json,但是每次为了一 ...
- Spring controller 中接收JSON参数失败
如果方法中的参数都是JSON类型,则在方法参数前面添加 @RequestBody 注解: public Boolean serverPath(@RequestBody ServerPathReq r ...
- springmvc接收json注意事项
在以前使用SpringMvc框架时,在接受json数据时碰到了一些奇怪的问题.这里记录下来,方便以后查阅. 1. data 里写json对象 , 即该json数据没有被单(双)引号包住 ...
- webapi 控制器接收POST参数时必须以对象的方式接收
webapi 控制器接收POST参数时必须以对象的方式接收
- spring接收json格式的多个对象参数(变通法)
两种方法 方法1 如果使用spring mvc同客户端通信,完全使用json数据格式,需要如下定义一个RequestMapping @Controller public class TestContr ...
- Servlet端 接收不到4096,8192长度的JSON参数
Servlet端的日志显示,客户端传过来的JSON参数是空值. 但是在客户端的日志显示,已将JSON参数传送过去. 经调查发现,加减1位后的JSON参数均可以正常传送. 只有8192,4096长度的J ...
- [置顶]
webapi token、参数签名是如何生成的
一个问题 在这里我想问大家一句,如果你向一个刚刚接触.net web后端程序开发的同学(别人刚刚也就学了webform的request,response,会提交表单的这种刚接触不久的同学),你怎么去解 ...
随机推荐
- html5的web存储
在html5标准之前,web存储信息需要cookie来完成,但是cookie不适合大量数据存储.因为需要等待服务器响应,所以速度慢/效率低. 本地存储的特点: localstorage是仅存储在用户的 ...
- 代码的坏味道(15)——冗余类(Lazy Class)
坏味道--冗余类(Lazy Class) 特征 理解和维护类总是费时费力的.如果一个类不值得你花费精力,它就应该被删除. 问题原因 也许一个类的初始设计是一个功能完全的类,然而随着代码的变迁,变得没什 ...
- angluarjs2项目生成内容合并到asp.net mvc4项目中一起发布
应用场景 angular2(下文中标注位NG2)项目和.net mvc项目分别开发,前期采用跨域访问进行并行开发,后期只需要将NG2项目的生产版本合并到.net项目. NG2项目概述 ng2项目采用的 ...
- Android—万能ListView适配器
ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义. 最近参考一些资料,发现一个万能ListView适配器,代码量少,节省时间,总结一下分享给大家. 首先有一个自定义的 ...
- 微信小程序监控 - HotApp统计
HotApp小程序统计,第一个专业的微信第三方小程序监控统计工具 1.什么是HotApp小程序统计 HotApp小程序统计是第一个微信第三方小程序统计工具,就像做android 和 ios开发的人知道 ...
- git和pycharm管理代码
首先明白三个概念,服务器代码库,本地代码库,和正在coding的项目. coding完毕后,先通过commit提交到本地代码库,然后通过push再提交server的代码库 git步骤 git c ...
- 深入学习HBase架构原理
HBase定义 HBase 是一个高可靠.高性能.面向列.可伸缩的分布式存储系统,利用Hbase技术可在廉价PC Server上搭建 大规模结构化存储集群. HBase 是Google Bigtabl ...
- Apache2.4:AH01630 client denied by server configuration
问题说明:Apache服务总共有4个,是为了防止单点故障和负载均衡,负载均衡控制由局方的F5提供. 访问的内容在NAS存储上,现象是直接访问每个apache的服务内容都是没有问题,但是从负载地址过来的 ...
- ramdisk plus v11.5安装内存虚拟硬盘
ramdisk plus v11.5.桌面版操作及应用图解说明 一.ramdisk plus程序安装方法: 1.先安装英文原版软件(RamDisk-desktop.exe桌面版),安装路径不要更改,安 ...
- MyBatis2:config.xml文件
前言 前一篇文章,讲了MyBatis入门,讲到了MyBatis有两个基本的配置文件,一个用来配置环境信息,一个用来写SQL语句.前者我把它命名为config.xml,config.xml的内容是: & ...