
·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 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