運行環(huán)境:asp.net 4.5.2。
當(dāng)我們向GlobalConfiguration.Configuration.MessageHandlers添加一個DelegatingHandler派生類后,很容易發(fā)生即使命中了Action,但方法參數(shù)值為null的問題。
在大多數(shù)情況下,我們會在DelegatingHandler派生類里,重寫async Task<HttPResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)方法。
在方法內(nèi),做一些事情,比如說訪問日志記錄,任意校驗,添加Header,修改URL(重寫)等工作。
其中最重要需要注意的一點在于request.Content,當(dāng)我們在方法內(nèi)訪問了request.Content (get)之后,而不對request.Content進行賦值(set)的話,會發(fā)生什么呢?
這會導(dǎo)致我們的方法(action)無法獲取到客戶端Post上來的數(shù)據(jù),導(dǎo)致方法參數(shù)值為null。
這是為什么呢,這個中原因,我沒去深究。
現(xiàn)在附上解決代碼:
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進行業(yè)務(wù)處理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進行業(yè)務(wù)處理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進行業(yè)務(wù)處理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 : ApiController2 {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測試:
測試結(jié)果:
解決辦法來自:http://stackoverflow.com/questions/27333419/modify-request-content-in-webapi-delegatinghandler
新聞熱點
疑難解答