ASP.NET web api 无法获取 application/x-www-form-urlencoded HTTP POST

Posted

技术标签:

【中文标题】ASP.NET web api 无法获取 application/x-www-form-urlencoded HTTP POST【英文标题】:ASP.NET web api cannot get application/x-www-form-urlencoded HTTP POST 【发布时间】:2013-12-20 14:02:29 【问题描述】:

我是 web-api 的新手。我想使用 web-api 接收 HTTP POST 数据。 content-type 是application/x-www-form-urlencoded,请求体是这样的:

data="mac":"0004ED123456","model":"SG6200NXL"(JSON 格式)。

我的控制器是这样的:

public void Post([FromBody]string formData)

    data.Add(formData);

但 formData 始终为空。仅当我将请求正文更改为:

="mac":"0004ED123456","model":"SG6200NXL"

我可以找到"mac":"0004ED123456","model":"SG6200NXL" 保存在我的formData 字符串中。

所以我的问题是我应该如何接收格式的数据:

data="mac":"0004ED123456","model":"SG6200NXL"?

有没有一种简单的方法可以将 JSON 淡化为 C#?

感谢您的帮助!

更新: 我尝试使用模型,但它仍然不适合我。 我的模型是:

public class Device
    
        public string mac  get; set; 
        public string model  get; set; 
    

我的 HTTP POST 请求是:

标题:

User-Agent: Fiddler
Content-type: application/x-www-form-urlencoded
Host: localhost:52154
Content-Length: 46

正文:

data="mac":"0004ED123456","model":"SG6200NX"

据我所知,我必须使用Content-type: application/x-www-form-urlencoded,因为 HTTP POST 是由路由器发送的。我的工作是接收数据。

【问题讨论】:

【参考方案1】:

引用here:

默认情况下,Web API 会尝试从请求 URI 中获取简单类型。 FromBody 属性告诉 Web API 从请求正文中读取值。

Web API 最多读取一次响应正文,因此一个动作的一个参数只能来自请求正文。如果您需要从请求正文中获取多个值,请定义一个复杂类型。

其次,客户端需要发送如下格式的值:

=值

具体来说,对于简单类型,名称/值对的名称部分必须为空。

所以,如果要以data=string 格式发布数据,则必须创建复杂类型。

public class MyFormData

    public string Data  get; set; 

然后像这样更新你的控制器:

public void Post(MyFormData formData)

    //your JSON string will be in formData.Data

当然,您的其他选择是将内容类型更改为 JSON,但实际上取决于您的要求。

【讨论】:

我试过这种方式,但它仍然不适合我。请看我的更新。感谢您的帮助。 如果您以mac=string&model=string 格式发送数据,您更新的Device 模型将起作用。但是您的格式是data=string,因此您必须拥有一个名为data 的属性,正如我在回答中所展示的那样。 如果名称有连字符,如何将表单数据映射到我的班级?比如数据="mac":"0004ED123456","model":"SG6200NX","device-id":"aUniqueId" @jplara - 我认为您可能需要使用自定义格式化程序 - c-sharpcorner.com/article/… 我找到了另一个选项,自定义格式化程序对我来说太过分了,你可以接受FormDataCollection,这样你就可以访问发布的数据【参考方案2】:

这篇文章很旧,但我在寻找答案时偶然发现了它。我会发布我是如何让我的工作的,也许有人会觉得它有用。

这是请求:

POST /api/values HTTP/1.1
Host: localhost:62798
Accept: text/json
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 51ee1c5f-acbb-335b-35d9-d2b8e62abc74

UID=200&EMAIL=john%40jones.com&FIRST_NAME=John&LAST_NAME=jones&PHONE=433-394-3324&CITY=Seattle&STATE_CODE=WA&ZIP=98105

这是模型:

public class SampleModel
    public string UID  get; set; 

    public string Email  get; set; 

    public string First_Name  get; set; 

    public string Last_Name  get; set; 

    public string Phone  get; set; 

    public string City  get; set; 

    public string State_Code  get; set; 

    public string Zip  get; set; 

这是自动(FromBody)将 urlencoded 值转换为模型的 POST 方法。

public HttpResponseMessage Post([FromBody] SampleModel value)

我能够挑选出任何价值,即

    SearchCity(value.City);
    SearchName(value.Last_Name);

【讨论】:

【参考方案3】:

您应该创建一个数据对象,例如:

public class Device

  public string mac get;set;
  public string model get;set;

然后像这样更改控制器的操作方法,并将对象从消耗传递给此方法

public void Post(Device deviceData)

    // You can extract data like deviceData.mac, deviceData.model etc
    data.Add(deviceData);

您可以使用流行的库之一json.net 在 C# 中对 json 对象进行序列化/反序列化

【讨论】:

我试过你的方法,但它似乎不适合我。我仍然得到空值。我的 post 请求标头是 User-Agent: Fiddler Content-type: application/x-www-form-urlencoded Host: localhost:52154,请求正文是 data="mac":"0004ED123456","model":"SG6200NX ",我只能看到一个空值添加到我的数据字符串列表中。【参考方案4】:

创建模型

public class MyClass 
    public string mac  get; set; 
    public string model  get; set; 

并使用 .net javascriptSerializer().Deserialize

public void Post([FromBody]string formData)
    MyClass obj = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<MyClass>(formData);
    //get mac and model by obj.mac obj.model

干杯:)

【讨论】:

完全没有必要自己序列化模型。【参考方案5】:

对于 asp.net core 3.x,您需要提供正确的装饰器来正确处理请求:

[HttpPost("MyPostHandler")]
[Consumes("application/x-www-form-urlencoded")]
public async Task<IActionResult> MyPostHandler([FromForm] string id)


【讨论】:

【参考方案6】:

如果您使用的是 Content-type: application/x-www-form-urlencoded 您不能期望收到 JSON。

我猜您正在使用表单将数据发送到 Web Api 控制器?

首先您必须将 Content-type 更改为 application/json,然后您必须确保在请求正文中发送 JSON 数据。如果您通过表单发送数据,您可以使用 javascript 从表单数据中创建 JSON 对象。

要在 C# 中反序列化 JSON,我推荐 Json.NET:http://json.codeplex.com/

【讨论】:

以上是关于ASP.NET web api 无法获取 application/x-www-form-urlencoded HTTP POST的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 asp.net Web API 2(使用 TPL/Reactive)缓冲和批处理 REST 获取查询?

为啥 ASP.NET web api 3 项目在 ASP.NET web api 2 执行时没有请求就无法启动?

ASP.NET Core Web API InvalidOperationException:无法解析服务 [重复]

从 ASP.NET Web API ASP.NET Core 2 返回 HTML 并获取 http 状态 406

ASP.NET Core Web API:尝试激活时无法解析服务类型

ASP.NET Web API 无法从 POST 正文中读取