webapi的参数反序列化是根据HTTP请求中的Content-type
现在有这样一个场景
在发起HTTP请求都时候,ContentType不填或者随意填,Action内接收的参数按照json格式反序列化
思路1.
通过某种方式在参数序列化之前改变HTTP请求的ContentType,或者让web api进行参数反序列化的时候读取的ContentType为我们想要的值。
比如在请求的时候填写Content-Type:text/plain
然后经过某种处理,在webapi进行反序列化的时候他读到的Content-Type:application/json。
然后他按照json格式去处理
思路2.
设定类似于Content-Type填写application/json映射参数使用json反序列化这样的映射,比如我在url中写type=json,即可映射为使用json格式反序列化参数。
通过以下这种方式似乎是配置返回值的序列化方式的,并不影响接收参数的反序列化。
QueryStringMapping jsonMapping = new QueryStringMapping("type", "json", "application/json"); GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(jsonMapping);
这两种哪一种可以行得通呢,或者有更好的解决办法解决这个问题。
求解惑。
上个帖子中有朋友提到在filter判定,但是并不好使。。因为使用actionContext.ActionArguments;都可以获取到反序列化的参数了- - 再去设置headers也无甚意义吧。
单独项目下载地址:http://pan.baidu.com/s/1mufYY
void ConfigureApi(HttpConfiguration config) { // Remove the JSON formatter config.Formatters.Remove(config.Formatters.JsonFormatter); // or // Remove the XML formatter config.Formatters.Remove(config.Formatters.XmlFormatter); }
这个是控制返回值序列化的吧
移除掉xml,content-type留空,依然不会按json方式反序列化参数
@空葫芦: 我假设你的一个 WebApi 是这样的:
class User {public string Name{get;set;} public string Password{get;set;}};
[HttpPost]
int Get(User user);
然后你构造了一个 HTTP 请求,同时不填写 Header 的 Content-Type ,BODY 的内容是:{Name:"A",Password:"B"},然后你将此请求提交给服务器,服务收到后没有将此 BODY 反序列化成 User 实例,是这个意思吗?如果是,服务有异常吗?
@Launcher: 对,是你描述的那样。
服务没有异常。而且这跟服务没关系吧,调试到方法第一句,发现参数没有被成功反序列化就是失败了的。
现在使用自定义的HttpParameterBinding解决了。
只是不知有没有更简便的方法。
@空葫芦: 我说的服务就是你的 Asp.Net Web Api,你这里的“调试到方法第一句”是指的 Web Api 的源码吧。如果请求的 Content-type 同 BODY 的实际类型不符和,Web Api 不报异常的话,那么程序在排查错误上就很困难了,这同 WCF 设计不太一样。
你想要的其实就是自定义参数绑定(http://www.strathweb.com/2013/04/asp-net-web-api-parameter-binding-part-1-understanding-binding-from-uri/),目前看来这也是解决你的问题的唯一的方法。
@Launcher: 那个方法第一句是指Action的第一句。web api的源码也去看了,可以通过修改配置让Content-Type为非application/json的请求也能正确反序列化,但是Content-Type值不能为空也不能非法。
请求的Content-Type为空,body中是json格式的数据,也没有找到其他办法去知会web api按照json格式反序列化。
目前也就先这样解决了。