ASP.NET Core dari POST menghasilkan respons HTTP 415 Jenis Media yang Tidak Didukung


173

Mengirim formulir POST HTTP request ( Content-Type: application/x-www-form-urlencoded) ke pengontrol di bawah ini menghasilkan respons HTTP 415 Jenis Media yang Tidak Didukung .

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

Bentuk pos tajuk 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

Ini digunakan untuk bekerja dengan ASP.NET MVC 5 di .NET 4.6.


Anda tidak harus menggunakan [FromForm] "Kirim (model MyModel)" juga mendapatkan model dengan benar.
— hasan

Jawaban:


298

Untuk formulir, gunakan [FromForm]atribut alih-alih [FromBody]atribut.

Pengontrol di bawah ini berfungsi dengan ASP.NET Core 1.1:

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

Catatan: [FromXxx]diperlukan jika controller Anda dijelaskan dengan [ApiController]. Untuk pengontrol tampilan normal, ini dapat dihilangkan.


104

Anda dapat menggunakan [FromBody]tetapi Anda perlu mengatur Content-Typeheader permintaan Anda application/json, yaitu

Content-Type: application/json

1
Itu sebabnya pertanyaan secara khusus menyebutkan bentuk POST, dengan tipe konten application/x-www-form-urlencoded. Suka dari <form>pada halaman HTML.
— Bart Verkoeijen

Ini bermanfaat bagi saya, karena saya mengirimkan objek, bukan formulir. Jawaban yang diterima adalah yang paling benar untuk OP, yang sudah menggunakan tipe konten yang benar untuk [FromForm]. Tetap saja, aku senang yang ini juga ada di sini. :)
— Ken Lyon

1
Ini sama sekali tidak menjawab pertanyaan. Pertanyaannya adalah bagaimana membuat badan formulir dukungan server, bukan bagaimana hanya memberi tahu semua klien Anda untuk berhenti mengirim mereka!
— csauve

Tunggu, apakah itu berarti tidak mungkin untuk mengambil konten dari tubuh permintaan yang berbeda dari application/json, seperti application/text? @ BartVerkoeijen ada ide?
— SpiritBob

10

Pertama, Anda perlu menentukan di Headers Content-Type, misalnya, bisa application/json.

Jika Anda mengatur application/jsonjenis konten, maka Anda perlu mengirim json.

Jadi dalam bodypermintaan Anda, Anda tidak akan mengirim form-data, x-www-for-urlencodedtetapi rawjson, misalnya{"Username": "user", "Password": "pass"}

Anda dapat menyesuaikan contoh dengan berbagai jenis konten, termasuk apa yang ingin Anda kirim.

Anda dapat menggunakan alat seperti tukang pos atau ikal untuk bermain dengan ini.


6

Sebagai tambahan jawaban yang bagus, Anda tidak harus menggunakan [FromForm]untuk mendapatkan data formulir di controller. Kerangka kerja secara otomatis mengonversi data formulir ke model yang Anda inginkan. Anda dapat menerapkan seperti berikut.

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

3
Bukan apa yang saya lihat.
— François

Saya telah mengujinya dan ternyata berfungsi, Mungkin ada masalah lain dengan kode Anda
— hasan

Ini menyelesaikan masalah saya. Saya sedang memperbaiki objek FormData dengan bidang dan file di dalamnya, [FromForm] atau [FromBody] tidak berfungsi. Dihapus dan berhasil. (Asp.Net MVC Core 2.1 kembali, vanilla js depan). Intinya di sini .
— Daniel Szabo

Lucu, beberapa bulan setelah komentar saya sebelumnya - hari ini saya memiliki masalah yang sama dalam proyek AspNetCore 2.2 Web Api, dan saya harus menggunakan [FromFrom] untuk membuatnya bekerja di pengontrol WebAPI (lihat jawaban @ Bart).
— Daniel Szabo

1
Bagi saya, saya memiliki [FromQuery]parameter, tetapi saya tidak menentukan Tipe Konten sebagai application/json- menambahkan bahwa dalam permintaan saya, membuat ini berfungsi dengan parameter [FromQuery] juga.
— Mike Upjohn

5

Ini adalah kasus saya: dijalankan Lingkungan: AspNet Core 2.1 Controller:

public class MyController
{
    // ...

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

Melihat:

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

2

masalahnya bisa karena MVC MW. Anda harus mengatur formatterType dalam opsi 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;
            });

Di mana opsi. GunakanCustomStringModelBinder () tersedia ?? Saya tidak menemukan dokumentasi di tempat mana pun.
— Fabricio Araujo

0

"HTTP 415 Respons Jenis Media yang Tidak Didukung" berasal dari Content-Type di header permintaan Anda. misalnya dalam javascript oleh axios:

Axios({
            method: 'post',
            headers: { 'Content-Type': 'application/json'},
            url: '/',
            data: data,  // an object u want to send
          }).then(function (response) {
            console.log(response);
          });
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.