简体   繁体   English

ASP.NET 核心表单 POST 结果为 HTTP 415 Unsupported Media Type 响应

[英]ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response

Sending a form POST HTTP request ( Content-Type: application/x-www-form-urlencoded ) to the below controller results into a HTTP 415 Unsupported Media Type response.将表单 POST HTTP 请求( Content-Type: application/x-www-form-urlencoded )发送到以下 controller 会导致HTTP 415 Unsupported Media Type响应。

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

Form post HTTP headers:表单发布 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

This used to work with ASP.NET MVC 5 on .NET 4.6.这曾经在 .NET 4.6 上与 ASP.NET MVC 5 一起使用。

For forms, use the [FromForm] attribute instead of the [FromBody] attribute.对于表单,请使用[FromForm]属性而不是[FromBody]属性。

The below controller works with ASP.NET Core 1.1:以下控制器适用于 ASP.NET Core 1.1:

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

Note: [FromXxx] is required if your controller is annotated with [ApiController] .注: [FromXxx]如果你的控制器与注释的需要[ApiController] For normal view controllers it can be omitted.对于普通的视图控制器,它可以省略。

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

Content-Type: application/json

First you need to specify in the Headers the Content-Type , for example, it can be application/json .首先,您需要在 Headers 中指定Content-Type ,例如,它可以是application/json

If you set application/json content type, then you need to send a json.如果您设置了application/json内容类型,那么您需要发送一个 json。

So in the body of your request you will send not form-data , not x-www-for-urlencoded but a raw json, for example {"Username": "user", "Password": "pass"}因此,在您的请求body ,您将发送的不是form-data ,不是x-www-for-urlencoded而是raw json,例如{"Username": "user", "Password": "pass"}

You can adapt the example to various content types, including what you want to send.您可以使示例适应各种内容类型,包括您要发送的内容。

You can use a tool like Postman or curl to play with this.你可以使用像 Postman 或 curl 这样的工具来玩这个。

As addition of good answers, You don't have to use [FromForm] to get form data in controller.作为补充的好答案,您不必使用[FromForm]来获取控制器中的表单数据。 Framework automatically convert form data to model as you wish.框架会根据需要自动将表单数据转换为模型。 You can implement like following.您可以实现如下。

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

This is my case: it's run Environment: AspNet Core 2.1 Controller:这是我的情况:它运行环境:AspNet Core 2.1 控制器:

public class MyController
{
    // ...

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

View:查看:

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

the problem can because of MVC MW.you must set formatterType in MVC options:问题可能是由于 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;
            });

Follow the below steps:请按照以下步骤操作:

  1. Add to sending request header Content-Type field:添加到发送请求头Content-Type字段:

     axios.post(`/Order/`, orderId, { headers: {'Content-Type': 'application/json'} })
  2. Every data (simple or complex type) sent with axios should be placed without any extra brackets ( axios.post('/Order/', orderId, ...) ).使用 axios 发送的每个数据(简单或复杂类型)都不应放置任何额外的括号( axios.post('/Order/', orderId, ...) )。

WARNING!警告! There is one exception for string type - stringify it before send ( axios.post('/Order/', JSON.stringify(address), ...) ). string类型有一个例外 - 在发送之前对其进行string化( axios.post('/Order/', JSON.stringify(address), ...) )。

  1. Add method to controller:向控制器添加方法:

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

In my case 415 Unsupported Media Types was received since I used new FormData() and sent it with axios.post(...) but did not set headers: {content-type: 'multipart/form-data'} .在我的情况下,收到了 415 Unsupported Media Types,因为我使用了new FormData()并使用axios.post(...)发送了它,但没有设置headers: {content-type: 'multipart/form-data'} I also had to do the same on the server side:我也必须在服务器端做同样的事情:

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

With .NET 5 I have a .NET API Controller method that looks like this:使用.NET 5我有一个 .NET API 控制器方法,如下所示:

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

I had this request:我有这个要求:

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

test

It resulted in the following Status Code response: 415 Unsupported Media Type它导致以下状态代码响应: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"
}

I then switched to Content-Type: application/json like the answer from @BjornBailleul says but got this error instead:然后我切换到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."
        ]
    }
}

Got it working by also encapsulate the string in quotation marks like this: "test" .通过将字符串封装在引号中来使其工作,如下所示: "test"

Complete working request:完成工作要求:

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

"test"

在此处输入图片说明

"HTTP 415 Unsupported Media Type response" stems from Content-Type in header of your request. “HTTP 415 Unsupported Media Type response”源于请求标头中的Content-Type for example in javascript by axios:例如在 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);
          });

Another trap of note is making sure you're not decorating controllers with the Consume Attribute as below:另一个值得注意的陷阱是确保您没有使用如下的Consume 属性装饰控制器:

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

This will fail with a 415 Unsupported Media Type if the upload is NOT JSON.如果上传不是 JSON,这将失败并显示415 Unsupported Media Type

A "friend of mine" was recently caught out by this like so:一个“我的朋友”最近被这样发现了:

public class MyFileUploadController : MyCustomController {

}

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

}

In my case, I received the HTTP 415 Unsupported Media Type response, since I specified the content type to be TEXT and NOT JSON, so simply changing the type solved the issue.就我而言,我收到了 HTTP 415 Unsupported Media Type 响应,因为我将内容类型指定为 TEXT 而不是 JSON,因此只需更改类型即可解决问题。 Please check the solution in more detail in the following blog post: https://www.howtodevelop.net/article/20/unsupported-media-type-415-in-aspnet-core-web-api请在以下博客文章中更详细地检查解决方案: https : //www.howtodevelop.net/article/20/unsupported-media-type-415-in-aspnet-core-web-api

In my case, I had a method in my controller which was requiring an input parameter;就我而言,我的控制器中有一个需要输入参数的方法; unfortunately, the caller (an HttpClient) wasn't passing it.不幸的是,调用者(一个 HttpClient)没有通过它。 Shame on me.真丢人。

You must specify Encoding and Content Type, for instance:您必须指定编码和内容类型,例如:

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

I copied a POST request & changed to GET in postman, then getting the 415 error.我在 postman 中复制了一个 POST 请求并更改为 GET,然后得到 415 错误。

the fix is to delete the key-value pair in Body, since this is a GET request.解决方法是删除 Body 中的键值对,因为这是一个 GET 请求。

在此处输入图像描述

ASP.NET Core: [FromBody] vs [FromForm] ASP.NET 核心:[FromBody] 与 [FromForm]

Use [FromForm] for traditional HTML form post capture.使用[FromForm]进行传统的 HTML 表单后期捕获。 It can be used to capture either a single field value (from the POST HTML data stored in the body of the Http Request)...它可用于捕获单个字段值(来自存储在 Http 请求正文中的 POST HTML 数据)...

[HttpPost]
public string EditByPost([FromForm] string field1)
{
  return "Success: " + field1;
}

...or you can capture the full form field set into a C# matching class... ...或者您可以将完整的表单字段集捕获到 C# 匹配 class...

[HttpPost]
public ActionResult EditByPost([FromForm] Form1 form)
{
   // Here I am just returning the full set of form fields
   // back as a JSON object.
   return new JsonResult(form);
}

// Here is the C# Class I created that matches the HTML
// form fields being captured by [FormForm]:
public class Form1
{
  public string field1 { get; set; }
  public string field2 { get; set; }
  public string field3 { get; set; }
}

[FormBody] works the same but it is a new form, requiring JavaScript and a Form data set formatted in JSON. It also is sent via the Http POST inside the body or payload section of the Request but requires you also send the 'application/json' Content-type plus form fields in JSON format. [FormBody]工作原理相同,但它是一个新表单,需要 JavaScript 和格式为 JSON 的表单数据集。它也通过 Http POST 在请求的正文或有效负载部分内发送,但还需要您发送 'application/ json' 内容类型加上 JSON 格式的表单字段。 Because regular HTML forms cannot do that yet in 2023, you must use JavaScript tricks.因为常规 HTML forms 在 2023 年还不能做到这一点,所以您必须使用 JavaScript 技巧。

[HttpPost]
public ActionResult EditByPost([FromBody] Form1 form)
{
    return new JsonResult(form);
}

To call the JavaScript-JSON [FormBody] WebAPI above, you have to use JavaScript and extract out the form fields from the HTML then send them with the JSON data and JSON content-type to the server:要调用上面的 JavaScript-JSON [FormBody] WebAPI,您必须使用 JavaScript 并从 HTML 中提取表单字段,然后将它们与 JSON 数据和 JSON 内容类型一起发送到服务器:

async function JavaScriptPOST() {
  const response = await fetch('https://example.com/editbypost',
  {
    method: 'POST',
    body: JSON.stringify({
      formfield1: value,
      formfield2: value,
      formfield2: value
    }),
    headers: {
      'Content-type':'application/json; charset=UTF-8',
    }
  }).then(...);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET 核心 WebAPI:不支持的媒体类型 - HTTP 415 - ASP.NET Core WebAPI: Unsupported Media Type - HTTP 415 415 不支持的媒体类型 asp.net 核心 - 415 Unsupported Media Type asp.net core Web API ASP.NET 核心发布请求 415 不支持的媒体类型 - Web API ASP.NET Core Post Request 415 Unsupported Media Type POST到内容类型为x-www-form-urlencoded的asp.net Web API会引发错误415不支持的媒体类型 - POST to asp.net web api with content type x-www-form-urlencoded raises error 415 unsupported media type ASP.NET Core 中内容类型“application/csp-report”的“415 Unsupported Media Type” - "415 Unsupported Media Type" for Content-Type "application/csp-report" in ASP.NET Core .NET Core API 中的 Twilio StatusCallBack &amp; Gather POST 方法返回 HTTP 415 - 不支持的媒体类型 - Twilio StatusCallBack & Gather POST method in .NET Core API returning HTTP 415 - Unsupported Media Type WebClient.UploadFile 到 IIS 7 中托管的 ASP.NET MVC 产生 HTTP 415:不支持的媒体类型错误 - WebClient.UploadFile to ASP.NET MVC hosted in IIS 7 produces HTTP 415: Unsupported media type error 错误 415:不支持的媒体类型 - ASP.NET MVC - Error 415: Unsupported Media Type - ASP.NET MVC 将带有 JSON 数据的 GET 请求从 Axios 发送到 Asp.net 核心 ActionResult 而不获取(415 不支持的媒体类型) - Send GET request with JSON data from Axios to Asp.net core ActionResult without getting (415 Unsupported Media Type) Angular7 - .NET Core v2 抛出 http 415(不支持的媒体类型) - Angular7 - .NET Core v2 throws http 415 (Unsupported Media Type)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM