Il modulo POST ASP.NET Core genera una risposta di tipo di supporto HTTP 415 non supportato


173

L'invio di una richiesta HTTP POST del modulo ( Content-Type: application/x-www-form-urlencoded) al controller sottostante si traduce in una risposta di tipo di supporto non supportato HTTP 415 .

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

Intestazioni HTTP post modulo:

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

In passato funzionava con ASP.NET MVC 5 su .NET 4.6.


non è necessario utilizzare [FromForm] "Invia (modello MyModel)" anche ottenere il modello correttamente.
Hasan

Risposte:


298

Per i moduli, utilizzare l' [FromForm]attributo anziché l' [FromBody]attributo.

Il controller di seguito funziona con ASP.NET Core 1.1:

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

Nota: [FromXxx]è richiesto se il controller è annotato con [ApiController]. Per i normali controller di visualizzazione può essere omesso.


104

È possibile utilizzare [FromBody]ma è necessario impostare l' Content-Typeintestazione della richiesta su application/json, ad es

Content-Type: application/json

1
Ecco perché la domanda menziona specificamente un modulo POST, con tipo di contenuto application/x-www-form-urlencoded. Come da a <form>su una pagina HTML.
Bart Verkoeijen,

Questo mi è stato utile, perché stavo inviando un oggetto, non un modulo. La risposta accettata è la più corretta per l'OP, che stava già utilizzando il tipo di contenuto corretto per [FromForm]. Tuttavia, sono contento che anche questo fosse qui. :)
Ken Lyon,

1
Questo non risponde affatto alla domanda. La domanda è come rendere i corpi dei moduli di supporto del server, non come semplicemente dire a tutti i tuoi clienti di smettere di inviarli!
csauve,

Aspetta, ciò significa che è impossibile ingerire contenuti dal corpo di una richiesta diverso da application/json, come application/text? @BartVerkoeijen qualche idea?
SpiritBob

10

Innanzitutto è necessario specificare nelle intestazioni Content-Type, ad esempio, può essere application/json.

Se imposti il application/jsontipo di contenuto, devi inviare un json.

Quindi nella bodyrichiesta non invierai form-data, non x-www-for-urlencodedun rawjson, per esempio{"Username": "user", "Password": "pass"}

È possibile adattare l'esempio a vari tipi di contenuto, incluso ciò che si desidera inviare.

Puoi usare uno strumento come Postman o curl per giocare con questo.


6

Come aggiunta di buone risposte, non è necessario utilizzare [FromForm]per ottenere i dati del modulo nel controller. Framework converte automaticamente i dati del modulo in modello come desideri. Puoi implementare come segue.

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

3
Non quello che vedo.
François

L'ho provato e funzionava, potrebbe esserci un altro problema con il tuo codice
hasan

Questo ha risolto il mio problema. Ajaxing un oggetto FormData con campi e file al suo interno, [FromForm] o [FromBody] non funzionava. Rimossi e ha funzionato. (Asp.Net MVC Core 2.1 posteriore, vaniglia js anteriore). Gist Here .
Daniel Szabo,

Divertente, qualche mese dopo il mio precedente commento - oggi ho avuto lo stesso problema nel progetto Api Web AspNetCore 2.2 e ho dovuto usare [FromFrom] per farlo funzionare in un controller WebAPI (vedi la risposta di @ Bart).
Daniel Szabo,

1
Per me avevo un [FromQuery]parametro, ma non stavo specificando Content-Type come application/json- aggiungendolo nella mia richiesta, ho fatto funzionare anche questo con il parametro [FromQuery].
Mike Upjohn,

5

Questo è il mio caso: è eseguito Ambiente: AspNet Core 2.1 Controller:

public class MyController
{
    // ...

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

Visualizza:

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

2

il problema può a causa di MVC MW. è necessario impostare formatterType nelle opzioni 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;
            });

Dove options.UseCustomStringModelBinder () è disponibile ?? Non ho trovato la documentazione in nessun posto.
Fabricio Araujo,

0

"HTTP 415 Risposta tipo di supporto non supportata" deriva da Content-Type nell'intestazione della richiesta. ad esempio in javascript da axios:

Axios({
            method: 'post',
            headers: { 'Content-Type': 'application/json'},
            url: '/',
            data: data,  // an object u want to send
          }).then(function (response) {
            console.log(response);
          });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.