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
作者:VAllen
出处:http://www.cnblogs.com/vallen
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
唯有偏执者得以生存。
出处:http://www.cnblogs.com/vallen
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
唯有偏执者得以生存。