运行环境:asp.net4.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。
这是为什么呢,这个中原因,我没去深究。
现在附上解决代码:
1publicclassDefaultHandler : DelegatingHandler2{3protectedoverrideasyncTask<HttpResponseMessage>SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)4{5request.RequestUri =newUri(request.RequestUri.ToString());67MediaTypeHeaderValue contentType =request.Content.Headers.ContentType;89if(contentType !=null)10{11switch(contentType.MediaType)12{13case"application/x-www-form-urlencoded":14{15NameValueCollection formData =awaitrequest.Content.ReadAsFormDataAsync(cancellationToken);16request.Content = new FormUrlEncodedContent(Correct(formData));17//TODO:在这里对formData进行业务处理18}19
break;20case"multipart/form-data":21{22NameValueCollection formData =awaitrequest.Content.ReadAsFormDataAsync(cancellationToken);23request.Content = new FormUrlEncodedContent(Correct(formData));24//TODO:在这里对formData进行业务处理25}26
break;27case"application/json":28{29HttpContentHeaders oldHeaders =request.Content.Headers;30stringformData =awaitrequest.Content.ReadAsStringAsync();31request.Content = new StringContent(formData);32ReplaceHeaders(request.Content.Headers, oldHeaders);33//TODO:在这里对formData进行业务处理34}35
break;36default:37thrownewException("Implement It!");38}39}4041returnawaitbase.SendAsync(request, cancellationToken);42}4344privatestaticIEnumerable<KeyValuePair<string,string>>Correct(NameValueCollection formData)45{46returnformData.Keys.Cast<string>().Select(key =>newKeyValuePair<string,string>(key, formData[key])).ToList();47}4849privatestaticvoidReplaceHeaders(HttpHeaders currentHeaders, HttpHeaders oldHeaders)50{51currentHeaders.Clear();52foreach(variteminoldHeaders)53currentHeaders.Add(item.Key, item.Value);54}55}
在Global.asax添加代码:
1protectedvoidApplication_Start()2{3GlobalConfiguration.Configure(WebApiConfig.Register);4GlobalConfiguration.Configuration.MessageHandlers.Add(new DefaultHandler());5}
模型类:
1publicclassTestModel2{3[JsonProperty(PropertyName ="I")]4publiclongId {get;set; }56[JsonProperty(PropertyName ="N")]7publicstringName {get;set; }89[JsonProperty(PropertyName ="M")]10publicdecimalMoney {get;set; }1112[JsonProperty(PropertyName ="IE")]13publicboolIsEnable {get;set; }1415[JsonProperty(PropertyName ="CD")]16publicDateTime CreateDate {get;set; }1718[JsonProperty(PropertyName ="UD")]19publicDateTime? UpdateDate {get;set; }20}
ApiController:
1publicclassDefaultController : ApiController2{3[HttpPost]4publicTestModel Find(TestModel model)5{6returnmodel;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测试:
[flash=500,400]http://s1.knowsky.com/20160211/jtcrypxqx3e14.png[/flash]
测试结果:
[flash=500,400]http://s1.knowsky.com/20160211/5oyrmrtlvt214.png[/flash]
[flash=500,400]http://s1.knowsky.com/20160211/oygncavvcxi14.png[/flash]
解决办法来自:http://stackoverflow.com/questions/27333419/modify-request-content-in-webapi-delegatinghandler