WebAPI DataMember通过application / x-www-form-urlencoded进行de / serial化时不使用的名称
处理HTTP POST表单请求时,已花费几个小时尝试解决DataMemberAttribute
上忽略的Name
属性的问题( Content-Type: application/x-www-form-urlencoded
)。
我在.NET 4.5上运行Microsoft.AspNet.WebApi 5.2.3
应用程序,由IIS托管。
我有这个模型(演示):
// library public interface IPayload { string DataId { get; set; } int RelationId { get; set; } } // web app project [DataContract] public class MyPayload : IPayload { [Required] [DataMember(Name = "id")] public string DataId { get; set; } [Required] [DataMember(Name = "rel")] public int RelationId { get; set; } }
然后我有控制器:
[HttpPost] [Route("~/api/stuff")] public async Task DoMagic(MyPayload payload) { // ... breakpoint }
(注意我实际上使用的是模型类型,而不仅仅是我的控制器中的接口)
当我发送这样的数据时:
curl -X POST --data '{"id":"foo","rel":1}' -H "Content-Type: application/json" -H "Content-Length: 20" http://localhost/api/stuff
我正确地反序列化了我的模型。
但是,当我这样做时:
curl --data "id=foo" --data "rel=1" http://localhost/api/stuff
…我得到空模型 – 忽略自定义名称,所有属性都有默认值。
最后,当我这样请求时:
curl --data "DataId=foo" --data "RelationId=1" http://localhost/api/stuff
…模型正确序列化。
所以我想知道,我做错了什么。 我花了很多时间阅读,我发现的大部分案例都是关于我的案例中缺少的DataContractAttribute
。
控制器参数前面的属性FromBody
也没有改变任何东西。
在我的应用程序中,这些格式化程序已注册:
-
System.Net.Http.Formatting.JsonMediaTypeFormatter
-
System.Net.Http.Formatting.XmlMediaTypeFormatter
-
System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
-
System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter
只有最后两个在SupportedMediaTypes
包含application/x-www-form-urlencoded
。
花在调试上的时间之后,我必须自己回答。
未使用System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
因为我的模型不是从FormDataCollection
派生的,也不是JS令牌类型。 所以格式化程序System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter
正在使用中。
CompositeModelBinder
中使用的绑定器是:
-
TypeMatchModelBinder
(跳过) -
MutableObjectModelBinder
(已使用)
我没有找到任何代码的痕迹,这将考虑DataMemberAttribute
Name
属性 – 所以我必须为我的类型实现自己的IModelBinder
,它将负责自定义。
请注意:序列化对象时,一切都按预期工作 – 上述问题仅与请求体的反序列化有关。
来源
- System.Net.Http.Formatting.Formatting
- System.Web.Http.ModelBinding
我希望我没有错过任何东西。 如果是这样,请纠正我。