zoukankan      html  css  js  c++  java
  • 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。

    这是为什么呢,这个中原因,我没去深究。

    现在附上解决代码:

     1 public class DefaultHandler : DelegatingHandler
     2 {
     3     protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
     4     {
     5         request.RequestUri = new Uri(request.RequestUri.ToString());
     6 
     7         MediaTypeHeaderValue contentType = request.Content.Headers.ContentType;
     8 
     9         if (contentType != null)
    10         {
    11             switch (contentType.MediaType)
    12             {
    13                 case "application/x-www-form-urlencoded":
    14                     {
    15                         NameValueCollection formData = await request.Content.ReadAsFormDataAsync(cancellationToken);
    16                         request.Content = new FormUrlEncodedContent(Correct(formData));
    17                         //TODO:在这里对formData进行业务处理
    18                     }
    19                     break;
    20                 case "multipart/form-data":
    21                     {
    22                         NameValueCollection formData = await request.Content.ReadAsFormDataAsync(cancellationToken);
    23                         request.Content = new FormUrlEncodedContent(Correct(formData));
    24                         //TODO:在这里对formData进行业务处理
    25                     }
    26                     break;
    27                 case "application/json":
    28                     {
    29                         HttpContentHeaders oldHeaders = request.Content.Headers;
    30                         string formData = await request.Content.ReadAsStringAsync();
    31                         request.Content = new StringContent(formData);
    32                         ReplaceHeaders(request.Content.Headers, oldHeaders);
    33                         //TODO:在这里对formData进行业务处理
    34                     }
    35                     break;
    36                 default:
    37                     throw new Exception("Implement It!");
    38             }
    39         }
    40 
    41         return await base.SendAsync(request, cancellationToken);
    42     }
    43 
    44     private static IEnumerable<KeyValuePair<string, string>> Correct(NameValueCollection formData)
    45     {
    46         return formData.Keys.Cast<string>().Select(key => new KeyValuePair<string, string>(key, formData[key])).ToList();
    47     }
    48 
    49     private static void ReplaceHeaders(HttpHeaders currentHeaders, HttpHeaders oldHeaders)
    50     {
    51         currentHeaders.Clear();
    52         foreach (var item in oldHeaders)
    53             currentHeaders.Add(item.Key, item.Value);
    54     }
    55 }

    在Global.asax添加代码:

    1 protected void Application_Start()
    2 {
    3     GlobalConfiguration.Configure(WebApiConfig.Register);
    4     GlobalConfiguration.Configuration.MessageHandlers.Add(new DefaultHandler());
    5 }

    模型类:

     1 public class TestModel
     2 {
     3     [JsonProperty(PropertyName ="I")]
     4     public long Id { get; set; }
     5 
     6     [JsonProperty(PropertyName = "N")]
     7     public string Name { get; set; }
     8 
     9     [JsonProperty(PropertyName = "M")]
    10     public decimal Money { get; set; }
    11 
    12     [JsonProperty(PropertyName = "IE")]
    13     public bool IsEnable { get; set; }
    14 
    15     [JsonProperty(PropertyName = "CD")]
    16     public DateTime CreateDate { get; set; }
    17 
    18     [JsonProperty(PropertyName = "UD")]
    19     public DateTime? UpdateDate { get; set; }
    20 }

    ApiController:

    1 public class DefaultController : ApiController
    2 {
    3     [HttpPost]
    4     public TestModel Find(TestModel model)
    5     {
    6         return model;
    7     }
    8 }

    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

  • 相关阅读:
    移动开发基础(二)touch事件
    js的性能优化
    理解Java的Class.forName()方法
    Linux 串口读写(一)
    PreparedStatement是如何大幅度提高性能的
    简单图像匹配(转)
    共享内存
    Oracle ORA12505, TNS:listener does not currently know of SID given in connect descriptor 解决
    Top Half & Bottom Half
    vue 插件 使用 Echarts 创建图表 (转)
  • 原文地址:https://www.cnblogs.com/VAllen/p/WebAPI-Post-Request-Json-Data-HttpPrameterBinder.html
Copyright © 2011-2022 走看看