将表单 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]
属性而不是 [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
首先,您需要在 Headers 中指定 Content-Type
,例如,它可以是 application/json
。
如果您设置 application/json
内容类型,那么您需要发送一个 json。
因此,在您的请求的 body
中,您将发送的不是 form-data
,不是 x-www-for-urlencoded
,而是一个 raw
json,例如 {"Username": "user", "Password": "pass"}
您可以使示例适应各种内容类型,包括您要发送的内容。
你可以使用 Postman 或 curl 之类的工具来玩这个。
作为良好答案的补充,您不必使用 [FromForm]
在控制器中获取表单数据。框架根据您的需要自动将表单数据转换为模型。您可以实现如下。
[HttpPost]
public async Task<IActionResult> Submit(MyModel model)
{
//...
}
[FromQuery]
参数,但我没有将 Content-Type 指定为 application/json
- 在我的请求中添加它,也可以使用 [FromQuery] 参数。
ApiController
时才需要 [FromForm]
属性。
这是我的情况:它运行环境: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>
在我的情况下,由于我使用 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 :( 为什么做这样一个基本的事情这么难..
请按照以下步骤操作:
添加到发送请求头 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
使用 .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
问题可能是由于 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;
});
另一个值得注意的陷阱是确保您没有使用 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 {
}
“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);
});
就我而言,我收到了 HTTP 415 Unsupported Media Type 响应,因为我将内容类型指定为 TEXT 而不是 JSON,因此只需更改类型即可解决问题。请在以下博客文章中更详细地查看解决方案:https://www.howtodevelop.net/article/20/unsupported-media-type-415-in-aspnet-core-web-api
就我而言,我的控制器中有一个需要输入参数的方法;不幸的是,调用者(一个 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");
不定期副业成功案例分享
application/x-www-form-urlencoded
。就像 HTML 页面上的<form>
一样。application/json
的请求正文中提取内容,例如application/text
? @BartVerkoeijen 有什么想法吗?