运行环境: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参数注意事项的更多相关文章

  1. WebApi传递JSON参数

    开发过程中经常进行JSON的传递,在WebApi中传递JSON字串时,会发现服务器端接收到不参数值,看下面代码 服务端: public void Post([FromBody]string value ...

  2. SpringBoot配置Swagger实例(POST接收json参数)

    工程目录结构: 首先,引入jar包,只需要以下两个即可 <dependency> <groupId>io.springfox</groupId> <artif ...

  3. SpringBoot:自定义注解实现后台接收Json参数

    0.需求 在实际的开发过程中,服务间调用一般使用Json传参的模式,SpringBoot项目无法使用@RequestParam接收Json传参 只有@RequestBody支持Json,但是每次为了一 ...

  4. Spring controller 中接收JSON参数失败

    如果方法中的参数都是JSON类型,则在方法参数前面添加  @RequestBody 注解: public Boolean serverPath(@RequestBody ServerPathReq r ...

  5. springmvc接收json注意事项

            在以前使用SpringMvc框架时,在接受json数据时碰到了一些奇怪的问题.这里记录下来,方便以后查阅. 1. data 里写json对象 , 即该json数据没有被单(双)引号包住 ...

  6. webapi 控制器接收POST参数时必须以对象的方式接收

    webapi    控制器接收POST参数时必须以对象的方式接收

  7. spring接收json格式的多个对象参数(变通法)

    两种方法 方法1 如果使用spring mvc同客户端通信,完全使用json数据格式,需要如下定义一个RequestMapping @Controller public class TestContr ...

  8. Servlet端 接收不到4096,8192长度的JSON参数

    Servlet端的日志显示,客户端传过来的JSON参数是空值. 但是在客户端的日志显示,已将JSON参数传送过去. 经调查发现,加减1位后的JSON参数均可以正常传送. 只有8192,4096长度的J ...

  9. [置顶] webapi token、参数签名是如何生成的

    一个问题 在这里我想问大家一句,如果你向一个刚刚接触.net web后端程序开发的同学(别人刚刚也就学了webform的request,response,会提交表单的这种刚接触不久的同学),你怎么去解 ...

随机推荐

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(69)-微信公众平台开发-功能概述

    系列目录 为什么要先发这个文章? 因为接下来的文章是关于微信开发的系列,心中一定要有一个概念,知道自己接下来要做什么功能. 而且微信到处都是坑,我首先要把微信与本地跑通起来才敢发布,否则中间出现坑导致 ...

  2. Android混合开发之WebView与Javascript交互

    前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...

  3. 终端mysql Operation not permitted错误解决方案

    前言 前段时间装mysql,就遇到了ln: /usr/bin/mysql: Operation not permitted的错误,网上好多方法都过时了,下边是我的解决方法 原因 这是因为苹果在OS X ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. Java类访问权限修饰符

    一.概要 通过了解Java4种修饰符访问权限,能够进一步完善程序类,合理规划权限的范围,这样才能减少漏洞.提高安全性.具备表达力便于使用. 二.权限表 修饰符 同一个类 同一个包 不同包的子类 不同包 ...

  6. Java之多态(二)

    package test05;import test06.Car1;public class DuoTai_Test02 { /**多个对象,一个形态 * Tiger.Lion.Snake → Ani ...

  7. 升级npm

    查看npm的所有版本 运行命令: npm view npm versions 命令运行后,会输出到目前为止npm的所有版本. [ '1.1.25', '1.1.70', '1.1.71', '1.2. ...

  8. Android 解析XML文件和生成XML文件

    解析XML文件 public static void initXML(Context context) { //can't create in /data/media/0 because permis ...

  9. 转: 如何高效利用GitHub

    注:写了很多使用哲学,有意思 from: http://www.yangzhiping.com/tech/github.html

  10. babel-loader-presets

    babel-loader的presets的设置有一定的顺序.es2015必须出现在stage-0前面,我记得这是因为es2015是ES6的标准,state-0等是对ES7一些提案的支持, state- ...