ASP。NET Core form POST将导致HTTP 415不支持的媒体类型响应

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

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

表单post 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

这在过去是与ASP一起工作的。NET MVC 5在。NET 4.6。

231804 次浏览

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

下面的控制器与ASP。NET Core 1.1:

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

注意:如果你的控制器用[ApiController]注释,[FromXxx]是必需的。对于普通的视图控制器,可以省略。

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

Content-Type: application/json

首先你需要在头文件中指定Content-Type,例如,它可以是application/json

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

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

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

你可以使用一个工具,如邮差或卷曲来玩这个。

作为好的答案的补充,你不必使用[FromForm]来获取控制器中的表单数据。框架自动将表单数据转换为您希望的模型。你可以像下面这样实现。

[HttpPost]
public async Task<IActionResult> Submit(MyModel model)
{
//...
}
这是我的案例:它运行了 环境:AspNet Core 2.1 控制器:< / p >
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>

这个问题可能是因为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;
});

“HTTP 415不支持的媒体类型响应”源于你请求头中的内容类型。例如在javascript中通过axios:

Axios({
method: 'post',
headers: { 'Content-Type': 'application/json'},
url: '/',
data: data,  // an object u want to send
}).then(function (response) {
console.log(response);
});

请遵循以下步骤:

  1. 添加到发送请求头Content-Type字段:

     axios.post(`/Order/`, orderId,
    {
    headers: {'Content-Type': 'application/json'}
    })
    
  2. 使用axios发送的每个数据(简单或复杂类型)都应该放置在没有任何额外括号的位置(axios.post('/Order/', orderId, ...))。

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

  1. 添加方法到控制器:

    [HttpPost]
    public async Task<IActionResult> Post([FromBody]int orderId)
    {
    return Ok();
    }
    

另一个值得注意的陷阱是确保你没有像下面这样用使用属性来装饰控制器:

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

如果上载不是JSON,则使用415不支持的媒体类型将失败。

“我的朋友”;最近被这样的人发现:

public class MyFileUploadController : MyCustomController {


}


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


}
在我的情况下,我收到了HTTP 415不支持的媒体类型响应,因为我指定的内容类型为文本而不是JSON,所以简单地改变类型解决了这个问题。 请在下面的博客文章中查看更详细的解决方案: https://www.howtodevelop.net/article/20/unsupported-media-type-415-in-aspnet-core-web-api < / p >

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

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

使用.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不支持的媒体类型

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

然后我切换到Content-Type: application/json,就像@BjornBailleul的答案所说的那样,但却得到了这个错误:

{
"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"

enter image description here

在我的情况下,我有一个方法在我的控制器需要一个输入参数;不幸的是,调用者(HttpClient)没有传递它。

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

        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");

我复制了一个POST请求在邮递员中更改为GET,然后得到415错误。

修复方法是删除Body中的键-值对,因为这是一个GET请求。

enter image description here