通过应用程序/ x-WWW的形式urlen codeD序列化的WebAPI数据成员名称不使用时,DE /应用程序、形式、成员、名称

2023-09-05 03:14:31 作者:做我枕边人

已经花了几个小时试图解决问题,忽略名称 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.

 
精彩推荐
图片推荐