ChatGPT解决这个技术问题 Extra ChatGPT

ASP.NET Core 表单 POST 导致 HTTP 415 Unsupported Media Type 响应

将表单 POST HTTP 请求 (Content-Type: application/x-www-form-urlencoded) 发送到以下控制器会导致 HTTP 415 Unsupported Media Type 响应。

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)" 也可以正确获取模型。

A
Austin Hanson

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

以下控制器适用于 ASP.NET Core 1.1:

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

注意:如果您的控制器带有 [ApiController] 注释,则需要 [FromXxx]。对于普通视图控制器,它可以省略。


S
Shimmy Weitzhandler

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

Content-Type: application/json

这就是为什么这个问题特别提到了一个 form POST,内容类型为 application/x-www-form-urlencoded。就像 HTML 页面上的 <form> 一样。
这对我很有帮助,因为我提交的是对象,而不是表单。接受的答案对于 OP 来说是最正确的,因为他已经为 [FromForm] 使用了正确的内容类型。不过,我很高兴这个也在这里。 :)
这根本不能回答这个问题。问题是如何使服务器支持表单正文,而不是如何告诉所有客户停止发送它们!
等等,这是否意味着不可能从不同于 application/json 的请求正文中提取内容,例如 application/text? @BartVerkoeijen 有什么想法吗?
G
Gabriel P.

首先,您需要在 Headers 中指定 Content-Type,例如,它可以是 application/json

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

因此,在您的请求的 body 中,您将发送的不是 form-data,不是 x-www-for-urlencoded,而是一个 raw json,例如 {"Username": "user", "Password": "pass"}

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

你可以使用 Postman 或 curl 之类的工具来玩这个。


B
Bernard Vander Beken

作为良好答案的补充,您不必使用 [FromForm] 在控制器中获取表单数据。框架根据您的需要自动将表单数据转换为模型。您可以实现如下。

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

不是我看到的。
我已经对其进行了测试,并且可以正常工作,您的代码可能存在另一个问题
这解决了我的问题。我正在使用其中包含字段和文件的 FormData 对象,[FromForm] 或 [FromBody] 不起作用。删除它们并且它起作用了。 (Asp.Net MVC Core 2.1 后面,vanilla js 前面)。 Gist Here
对我来说,我有一个 [FromQuery] 参数,但我没有将 Content-Type 指定为 application/json - 在我的请求中添加它,也可以使用 [FromQuery] 参数。
我已经更新了接受的答案,但@hasan 和@François 都是正确的。仅当控制器是 ApiController 时才需要 [FromForm] 属性。
Q
Quang Vu

这是我的情况:它运行环境: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>

V
Vitaly Leskiv

在我的情况下,由于我使用 new FormData() 并使用 axios.post(...) 发送但未设置 headers: {content-type: 'multipart/form-data'},因此收到了 415 个不受支持的媒体类型。我也必须在服务器端做同样的事情:

[Consumes("multipart/form-data")]
public async Task<IActionResult> FileUpload([FromForm] IFormFile formFile) { ... }

目前它不起作用,我仍然有一个带有 [Consumes("multipart/form-data")] 的 415,没有每个参数都为 null :( 为什么做这样一个基本的事情这么难..
@moff452 对于多部分,您必须使用自定义模型绑定器(如果您使用自定义模型),否则您最终会得到空值。
最后,我不需要装饰器或 [FromForm],我只是忘记将 {get;set;} 添加到每个属性......现在它就像一个魅力:)
1
1_bug

请按照以下步骤操作:

添加到发送请求头 Content-Type 字段:axios.post(`/Order/`, orderId, { headers: {'Content-Type': 'application/json'} }) 发送的每个数据(简单或复杂类型) axios 应放置在没有任何额外括号的情况下(axios.post('/Order/', orderId, ...))。

警告! string 类型有一个例外 - 在发送之前对其进行字符串化 (axios.post('/Order/', JSON.stringify(address), ...))。

向控制器添加方法: [HttpPost] public async Task Post([FromBody]int orderId) { return Ok(); }


O
Ogglas

使用 .NET 5,我有一个如下所示的 .NET API 控制器方法:

[HttpPost("{rootEntity}/{id}")]
public ActionResult Post(RootEntity rootEntity, int id, [FromBody] string message)
{
    ...
}

我有这个要求:

POST /api/Comment/1/1 HTTP/1.1
Host: localhost:12345
Content-Type: text/plain
Content-Length: 4

test

它导致以下状态代码响应:415 Unsupported Media Type

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
    "title": "Unsupported Media Type",
    "status": 415,
    "traceId": "00-e7ca54e9f313c24699c3ca4697b9363d-be4719bd10735245-00"
}

然后我像@BjornBailleul 的回答一样切换到Content-Type: application/json,但得到了这个错误:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-0549e2c73842c249a93c8dc2f817e250-796e99fc0000224d-00",
    "errors": {
        "$": [
            "'test' is an invalid JSON literal. Expected the literal 'true'. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
        ]
    }
}

通过将字符串封装在引号中,使其工作,如下所示:"test"

完成工作要求:

POST /api/Comment/1/1 HTTP/1.1
Host: localhost:12345
Content-Type: application/json
Content-Length: 6

"test"

https://i.stack.imgur.com/eatjM.png


如果您投反对票,请说出原因,否则很难改善答案。
h
hamid_reza hobab

问题可能是由于 MVC MW.you 必须在 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() 在哪里可用?我在任何地方都没有找到它的文档。
r
rism

另一个值得注意的陷阱是确保您没有使用 Consume Attribute 装饰控制器,如下所示:

[Produces("application/json")]
[Consumes("application/json")]
public class MyController : Controller

如果上传不是 JSON,这将失败并显示 415 Unsupported Media Type

一个“我的朋友”最近被这样的事情抓住了:

public class MyFileUploadController : MyCustomController {

}

[Produces("application/json")]
[Consumes("application/json")]
public class MyCustomController : ControllerBase {

}

M
Mahdi Jalali

“HTTP 415 Unsupported Media Type response”源于请求标头中的 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);
          });

K
Kristina Cer

就我而言,我收到了 HTTP 415 Unsupported Media Type 响应,因为我将内容类型指定为 TEXT 而不是 JSON,因此只需更改类型即可解决问题。请在以下博客文章中更详细地查看解决方案:https://www.howtodevelop.net/article/20/unsupported-media-type-415-in-aspnet-core-web-api


F
Francesco B.

就我而言,我的控制器中有一个需要输入参数的方法;不幸的是,调用者(一个 HttpClient)没有通过它。真丢人。


F
Francisco

您必须指定编码和内容类型,例如:

        var request = new HttpRequestMessage
        {
            Method = new HttpMethod("POST"),
            RequestUri = new Uri(CombineUrl(_baseUrl, _resource))
        };
        request.Content = new StringContent(contentBody, System.Text.Encoding.UTF8, "application/json");

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅