POST формы ASP.NET Core приводит к ответу HTTP 415 Unsupported Media Type

173

Отправка HTTP-запроса POST формы ( 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

Раньше он работал с ASP.NET MVC 5 в .NET 4.6.

Барт Verkoeijen
источник
вам не нужно использовать [FromForm] «Submit (модель MyModel)», чтобы получить модель правильно.
Хасан

Ответы:

298

Для форм используйте [FromForm]атрибут вместо [FromBody]атрибута.

Приведенный ниже контроллер работает с ASP.NET Core 1.1:

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

Примечание: [FromXxx]требуется, если ваш контроллер помечен [ApiController]. Для контроллеров обычного представления это может быть опущено.

Барт Verkoeijen
источник
104

Вы можете использовать, [FromBody]но вам нужно установить Content-Typeзаголовок вашего запроса application/json, т.е.

Content-Type: application/json
Бьорн Байеул
источник
1
Вот почему в вопросе конкретно упоминается форма POST с типом контента application/x-www-form-urlencoded. Как из <form>на странице HTML.
Барт Verkoeijen
Это было полезно для меня, потому что я отправлял объект, а не форму. Принятый ответ является наиболее правильным для ОП, который уже использовал правильный тип контента для [FromForm]. Тем не менее, я рад, что этот тоже был здесь. :)
Кен Лион
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]для получения данных формы в контроллере. Framework автоматически преобразует данные формы в модель по вашему желанию. Вы можете реализовать как следующее.

[HttpPost]
public async Task<IActionResult> Submit(MyModel model)
{
    //...
}
Hasan
источник
3
Не то, что я вижу.
Франсуа
Я проверил это, и оно работало, может быть другая проблема с вашим кодом
hasan
Это решило мою проблему. Я ajaxing объект FormData с полями и файлами в нем, [FromForm] или [FromBody] не работает. Удалил их и все заработало. (Asp.Net MVC Core 2.1 задняя часть, ванильная передняя часть JS). Суть здесь .
Даниэль Сзабо
Забавно, через несколько месяцев после моего предыдущего комментария - сегодня у меня была такая же проблема в проекте AspNetCore 2.2 Web Api, и мне пришлось использовать [FromFrom], чтобы он работал в контроллере WebAPI (см. Ответ @ Bart).
Даниэль
1
Для меня у меня был [FromQuery]параметр, но я не указывал Content-Type как application/json- добавив, что в моем запросе сделал эту работу также с параметром [FromQuery].
Майк Апджон
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. Вы должны установить formatterType в параметрах MVC:

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 () доступен ?? Я не нашел документацию об этом в любом месте.
Фабрицио Араужо
0

«HTTP 415 Unsupported Media Type response» происходит от Content-Type в заголовке вашего запроса. например в 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);
          });
Махди Джалали
источник