【发布时间】:2015-07-07 16:09:05
【问题描述】:
已经花了几个小时试图解决在处理 HTTP POST 表单请求 (Content-Type: application/x-www-form-urlencoded) 时忽略 DataMemberAttribute 上的 Name 属性的问题。
我在 .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<HttpResponseMessage> 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.JsonMediaTypeFormatterSystem.Net.Http.Formatting.XmlMediaTypeFormatterSystem.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatterSystem.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter
SupportedMediaTypes 中只有最后两个包含 application/x-www-form-urlencoded。
【问题讨论】:
-
您是否已经尝试过 [FromUri] 属性?
-
说实话,我并没有因为内容真的在正文中 - 如果我尝试使用它,我实际上得到了
null我也尝试了ModelBinder(空的,因为我还没有实现任何自定义活页夹),它对我也没有多大帮助。另外,我不会走这条路——对于 JSON,它可以工作,那我为什么要在这里实现 binder? -
但是您声明“在处理 HTTP POST 表单请求时 (
Content-Type: application/x-www-form-urlencoded)”? -
对不起,我的意思是当我的动作处理程序
DoMagic由于 POST 请求而被调用时。我期待请求正文中的数据(正如任何人都希望从 POST 获得的那样,对吧?:))——所以基本上,我正在发送 POST 有效负载。如果我发送带有适当Content-Type标头的 JSON,它就可以工作。当我提交表单时它不起作用(method="post")。 -
您的
RequestContext.RouteData和Request.Content是什么样的?我对 curl 不熟悉,但我看到的 here 与您的帖子有些不同。
标签: c# asp.net .net asp.net-web-api