已经花了几个小时试图解决问题,忽略名称
在 DataMemberAttribute
处理时的HTTP POST表单请求属性(内容类型:应用程序/ x-WWW的形式urlen codeD
)
Already spent couple of hours trying to resolve issue with ignored Name
property on DataMemberAttribute
when handling HTTP POST form request (Content-Type: application/x-www-form-urlencoded
).
我在 Microsoft.AspNet.WebApi 5.2.3
运行在.NET 4.5,由IIS托管的应用程序。
I'm having Microsoft.AspNet.WebApi 5.2.3
application running on .NET 4.5, hosted by IIS.
我有这样的模型(演示):
I have this model (demo):
// 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; }
}
然后,我有控制器:
Then I have controller:
[HttpPost]
[Route("~/api/stuff")]
public async Task<HttpResponseMessage> DoMagic(MyPayload payload)
{
// ... breakpoint
}
(请注意,我真正使用的模型类型,而不是在我的控制器只是接口)
(Note I'm really using model type and not just interface in my controller)
当我发送的数据是这样的:
When I send data like this:
curl -X POST --data '{"id":"foo","rel":1}' -H "Content-Type: application/json" -H "Content-Length: 20" http://localhost/api/stuff
我得到我的模型正确地反序列化。
I get my model deserialized correctly.
然而,当我做的:
curl --data "id=foo" --data "rel=1" http://localhost/api/stuff
...我收到空模型 - 自定义名称将被忽略,所有的属性都有默认值
... I'm getting empty model - custom name is ignored, all properties have default value.
最后,当我做要求是这样的:
Finally, when I do request like this:
curl --data "DataId=foo" --data "RelationId=1" http://localhost/api/stuff
...模型是正确的序列。
... model is serialized correctly.
所以,我想知道,我究竟做错了。我花了相当大量的阅读,最让我发现病例是失踪 DataContractAttribute
这是present在我的情况。
So I'm wondering, what am I doing wrong. I spent quite a lot of reading, most of cases I found were about missing DataContractAttribute
which is present in my case.
在控制器参数前面属性 FromBody
并没有改变任何东西为好。
Attribute FromBody
in front of controller parameter is not changing anything as well.
在我的应用程序,这些格式化的注册:
In my application, these formatters are registered:
System.Net.Http.Formatting.JsonMediaTypeFormatter
System.Net.Http.Formatting.XmlMediaTypeFormatter
System.Net.Http.Formatting.FormUrlEn codedMediaTypeFormatter
System.Web.Http.ModelBinding.JQueryMvcFormUrlEn codedFormatter
System.Net.Http.Formatting.JsonMediaTypeFormatter
System.Net.Http.Formatting.XmlMediaTypeFormatter
System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter
只有最后两个包含应用程序/ x-WWW的形式urlen codeD
在 SupportedMediaTypes
。
花费的时间调试后,我来回答自己。
After time spent on debugging, I have to answer myself.
System.Net.Http.Formatting.FormUrlEn codedMediaTypeFormatter
不作为我的模型不是从 FormDataCollection 也不是JS令牌类型。因此,格式化
System.Web.Http.ModelBinding.JQueryMvcFormUrlEn codedFormatter
正在使用中。
System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
is not used as my model is not derived from FormDataCollection
nor is JS token type. So formatter System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter
is in use.
在 CompositeModelBinder
的粘合剂是:
TypeMatchModelBinder
(跳过)
MutableObjectModelBinder
(使用)
TypeMatchModelBinder
(skipped)
MutableObjectModelBinder
(used)
我还没有发现任何痕迹的code,这将需要考虑名称
DataMemberAttribute - 所以我要实现自己的
IModelBinder
为我喜欢的类型,这将需要定制护理
I haven't found any trace of code, which would take in consideration Name
attribute of DataMemberAttribute
- so I have to implement own IModelBinder
for my type, which will take care of customization.
只要注意:序列化对象的时候,一切都将按预期 - 上述问题仅与来自请求主体反序列化
Just note: when serializing object, everything works as expected - issue described above is related only to deserializing from request body.
来源
System.Net.Http.Formatting.Formatting System.Web.Http.ModelBinding System.Net.Http.Formatting.Formatting System.Web.Http.ModelBinding我希望我没有错过任何东西。如果是这样,请大家指正。
I hope I haven't missed anything. If so, please correct me.