ASP.NET Core表单POST导致HTTP 415不支持的媒体类型响应


173

将表单POST HTTP请求(Content-Type: application/x-www-form-urlencoded)发送到以下控制器将导致HTTP 415不支持的媒体类型响应。

public class MyController : Controller
{
    [HttpPost]
    public async Task<IActionResult> Submit([FromBody] MyModel model)
    {
        //...
    }
}

表单发布HTTP标头:

POST /submit HTTP/1.1
Host: example.com:1337
Connection: keep-alive
Content-Length: 219
Pragma: no-cache
Cache-Control: no-cache
Origin: https://example.com:1337
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: https://example.com:1337/submit
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8,nl;q=0.6

这曾经与.NET 4.6上的ASP.NET MVC 5一起使用。


您不必使用[FromForm]“ Submit(MyModel model)”也可以正确获取模型。
哈桑

Answers:


298

对于表单,请使用[FromForm]属性而不是[FromBody]属性。

以下控制器可与ASP.NET Core 1.1配合使用:

public class MyController : Controller
{
    [HttpPost]
    public async Task<IActionResult> Submit([FromForm] MyModel model)
    {
        //...
    }
}

注意:[FromXxx]如果您的控制器带有注释,则为必填项[ApiController]。对于普通视图控制器,可以将其省略。


104

您可以使用,[FromBody]但您需要将Content-Type请求的标头设置为application/json,即

Content-Type: application/json

1
这就是为什么该问题专门提到带有content-type的POST 表单application/x-www-form-urlencoded。就像<form>在HTML页面上一样。
Bart Verkoeijen

这对我很有帮助,因为我提交的是对象而不是表单。对于已经使用[FromForm]正确的内容类型的OP,可接受的答案是最正确的。不过,我很高兴这个人也在这里。:)
肯·里昂,

1
这根本无法回答问题。问题是如何使服务器支持表单主体,而不是如何仅告诉所有客户端停止发送它们!
csauve

等等,这是否意味着不可能从请求的主体中提取不同于的内容application/json,例如application/text?@BartVerkoeijen有什么想法吗?
SpiritBob

10

首先,您需要在标题中指定Content-Type,例如,可以为application/json

如果设置application/json内容类型,则需要发送一个json。

所以在body你的要求,你会送不form-data,不x-www-for-urlencoded,但一个rawJSON,例如{"Username": "user", "Password": "pass"}

您可以使示例适应各种内容类型,包括要发送的内容。

您可以使用Postman或curl等工具来玩这个游戏。


6

作为良好答案的补充,您无需使用[FromForm]控制器中的表单数据。框架会根据需要自动将表单数据转换为模型。您可以像下面那样实现。

[HttpPost]
public async Task<IActionResult> Submit(MyModel model)
{
    //...
}

3
不是我所看到的。
弗朗索瓦(François)

我已经对其进行了测试,并且可以正常工作,您的代码可能还有另一个问题
hasan

这解决了我的问题。我正在对其中包含字段和文件的FormData对象进行修饰,[FromForm]或[FromBody]无法正常工作。删除他们,它的工作。(Asp.Net MVC Core 2.1后面,香草js前面)。 要点在这里
Daniel Szabo

有趣的是,在我上次发表评论后的几个月-今天,我在AspNetCore 2.2 Web Api项目中遇到了同样的问题,我不得不使用[FromFrom]使它在WebAPI控制器中运行(请参阅@Bart的答案)。
Daniel Szabo

1
对我来说,我有一个[FromQuery]参数,但是我没有将Content-Type指定为application/json-在我的请求中添加它,也使[FromQuery]参数也可以使用。
Mike Upjohn

5

这是我的情况:运行环境:AspNet Core 2.1控制器:

public class MyController
{
    // ...

    [HttpPost]
    public ViewResult Search([FromForm]MySearchModel searchModel)
    {
        // ...
        return View("Index", viewmodel);
    }
}

视图:

<form method="post" asp-controller="MyController" asp-action="Search">
    <input name="MySearchModelProperty" id="MySearchModelProperty" />
    <input type="submit" value="Search" />
</form>

2

该问题可能是由于MVC MW引起的。您必须在MVC选项中设置formatterType:

services.AddMvc(options =>
            {
                options.UseCustomStringModelBinder();
                options.AllowEmptyInputInBodyModelBinding = true;
                foreach (var formatter in options.InputFormatters)
                {
                    if (formatter.GetType() == typeof(SystemTextJsonInputFormatter))
                        ((SystemTextJsonInputFormatter)formatter).SupportedMediaTypes.Add(
                            Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse("text/plain"));
                }
            }).AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
            });

哪里有options.UseCustomStringModelBinder()?我在任何地方都找不到它的文档。
Fabricio Araujo

0

“ HTTP 415不支持的媒体类型响应”源自请求标头中的Content-Type。例如在axios的javascript中:

Axios({
            method: 'post',
            headers: { 'Content-Type': 'application/json'},
            url: '/',
            data: data,  // an object u want to send
          }).then(function (response) {
            console.log(response);
          });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.