【问题标题】:Accept x-www-form-urlencoded in Web API .NET Core在 Web API .NET Core 中接受 x-www-form-urlencoded
【发布时间】:2018-08-09 00:22:36
【问题描述】:

我有一个 .NET Core Web API,当我尝试向它发布一些包含一些 json 的数据时,它返回 415 Unsupported Media Error。以下是 Chrome 调试器中返回的部分内容:

Request URL:http://localhost:51608/api/trackAllInOne/set
Request Method:POST
Status Code:415 Unsupported Media Type
Accept:text/javascript, text/html, application/xml, text/xml, */*
Content-Type:application/x-www-form-urlencoded

action:finish
currentSco:CSharp-SSLA:__How_It_Works_SCO
data:{"status":"incomplete","score":""}
activityId:13
studentId:1
timestamp:1519864867900

我认为这与我的控制器不接受 application/x-www-form-urlencoded 数据有关 - 但我不确定。我试过用Consumes 装饰我的控制器,但这似乎不起作用。

[HttpPost]
[Route("api/trackAllInOne/set")]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult Post([FromBody] PlayerPackage playerPackage)
{ etc..}

非常感谢任何帮助。

以下代码在 .NET 4.6.1 中运行良好,我能够捕获和处理上面显示的帖子。

[ResponseType(typeof(PlayerPackage))]
public async Task<IHttpActionResult> PostLearningRecord(PlayerPackage playerPackage)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var id = Convert.ToInt32(playerPackage.ActivityId);
    var learningRecord = await _context.LearningRecords.FindAsync(id);
    if (learningRecord == null)
        return NotFound();
etc...

【问题讨论】:

  • 什么是PlayerPackage ?您是如何从 Front 发送请求的?
  • PlayerPackage 是从在线课程发送的信息,用于跟踪学生在该课程中的进度。我无法控制系统如何发布。我的 WebApi 的工作是捕获这些帖子并将它们保存在我的跟踪系统中。
  • 你想用data:{"status":"incomplete","score":""}接受数据还是想记录所有的body action:finish currentSco:CSharp-SSLA:__How_It_Works_SCO data:{"status":"incomplete","score":""} activityId:13 studentId:1 timestamp:1519864867900
  • 是的,我确实想接受 json 数据;{"status: "incomplete" 等。这是关键部分,也是阻止它工作的原因。当我删除 json 时,似乎工作正常 - 但 json 是我最需要的。
  • 以下代码在 .net 4.6.1 中用于相同帖子的正常工作:[ResponseType(typeof(PlayerPackage))] public async Task&lt;IHttpActionResult&gt; PostLearningRecord(PlayerPackage playerPackage) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var id = Convert.ToInt32(playerPackage.ActivityId); var learningRecord = await _context.LearningRecords.FindAsync(id); if (learningRecord == null) return NotFound();

标签: asp.net-core-2.0 asp.net-core-webapi


【解决方案1】:

我遇到了同样的问题。 FormDataCollection 没有格式化程序所需的默认构造函数。请改用 IFormCollection。

【讨论】:

  • 使用 [FromForm] 属性而不是 [FromBody]
  • public IActionResult Search([FromForm]IFormCollection type) { return Ok(); }
【解决方案2】:

尝试使用[FromForm] 而不是[FromBody]

public IActionResult Post([FromForm] PlayerPackage playerPackage)
  • FromBody> 从 JSON 绑定

  • FromForm> 从表单参数绑定

您也可以完全删除[FromBody] 然后试用。因为您期望 form-urlencoded 应该告诉它绑定到对象。

【讨论】:

  • 好的,您可以尝试的另一件事是完全删除它(不理想,但可以)。
  • 无论如何我们可以让它同时适用于 application/x-www-urlencoded 和 application/json?我正在创建两个具有相同路由名称的函数,并共享一个私有函数来完成这项工作,但我想知道是否有更简单的方法来支持 JSON 和 FORM 绑定。
  • Robin,拥有方法 2 签名是否有效。一个带有 [Consumes] 属性的 url 表单,另一个带有 application/json?然后一个有 [FromFrom] 和另一个 [FromBody]。一旦绑定,获取一种方法直接调用另一种方法。只是一个想法。未测试。我想如果您删除 [From...] 属性,它会解决的,但也许他们需要 [consumes] 属性来帮助?
  • 太棒了! [FromForm] 那也是我的错
【解决方案3】:

对于PlayerPackage,请求应该发送一个PlayerPackage Json Object,根据您的描述,您无法控制从其他地方发布的请求。

对于请求,它的类型是application/x-www-form-urlencoded,它会发送带有{"status":"incomplete","score":""的数据} 以字符串格式代替 Json 对象。如果你想接受{"status":"incomplete","score":""},建议你改成下面的方法,然后通过Newtonsoft.Json

[HttpPost]
[Route("~/api/trackAllInOne/set")]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult Post([FromForm] string data)
{
    PlayerPackage playerPackage = JsonConvert.DeserializeObject<PlayerPackage>(data);
    return Json(data);
}

【讨论】:

  • 我已经关注了这个,但是从邮递员发送时我的“数据”为空。知道为什么吗?
  • @r3plica,我会使用自定义类型而不是字符串。将数据放入类型本身,然后在 [FromForm] 旁边,放入 [FromForm] CustomType 请求,然后在该自定义类型中,访问数据属性(或属于表单编码请求的一部分的其他属性)。这就是我所做的,并且有效。
  • @firecape 我遇到了完全相同的问题,数据为空,前一个值为字符串。
【解决方案4】:

这对我有用:

[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult Post([FromForm]IFormCollection value)

【讨论】:

    猜你喜欢
    • 2019-05-18
    • 2020-03-11
    • 1970-01-01
    • 2014-05-19
    • 2019-01-03
    • 2012-08-06
    • 2020-01-12
    • 1970-01-01
    • 2020-02-18
    相关资源
    最近更新 更多