文章出處

運行環境: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


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()