ASP.NET Core:ottieni i dati dei moduli pubblicati in un controller API

 C Programming >> Programmazione C >  >> Tags >> API
ASP.NET Core:ottieni i dati dei moduli pubblicati in un controller API

Per ottenere i dati dei moduli pubblicati in un controller API (utilizzando l'attributo [ApiController]) in ASP.NET Core, utilizzare i parametri con l'attributo [FromForm].

[Route("api/[controller]")]
[ApiController]
public class LocationController : ControllerBase
{
	[HttpPost]
	public IActionResult Post([FromForm] string location)
	{
		//process the form data
		
		return Ok(location);
	}
}
Code language: C# (cs)

Una richiesta a questo endpoint sarebbe simile a questa:

POST /api/weather HTTP/1.1
Content-Type: application/x-www-form-urlencoded

location=United+StatesCode language: plaintext (plaintext)

I dati del modulo sono una stringa di coppie chiave-valore (es:location=United+States ). Il framework tenta di mappare i dati del modulo ai parametri facendo corrispondere le chiavi del modulo con i nomi dei parametri (o i nomi delle proprietà del modello).

Puoi mappare più campi modulo come parametri individuali, mappare a un modello e anche leggere direttamente i dati del modulo, se lo desideri. In questo articolo mostrerò esempi di ciascuno di questi scenari.

Mappa più campi modulo come parametri individuali

Supponiamo che il tuo modulo abbia due campi:Posizione e Temperatura. Puoi mappare questi campi come parametri individuali:

[Route("api/[controller]")]
[ApiController]
public class WeatherController : ControllerBase
{
	[HttpPost]
	public IActionResult Post([FromForm] string location, [FromForm] int temperature)
	{
		//process the parameters
		
		return Ok($"{location} {temperature}");
	}
}
Code language: C# (cs)

Ecco come sarebbe una richiesta a questo endpoint:

POST /api/weather HTTP/1.1
Content-Type: application/x-www-form-urlencoded

location=United+States&temperature=64Code language: plaintext (plaintext)

Nota:quando sono presenti più campi modulo, le coppie chiave-valore sono separate da una e commerciale (&).

Mappatura su un modello

Invece di mappare i campi modulo come parametri individuali, puoi mappare a un modello. Questa è una buona opzione perché esegue la convalida del modello.

[Route("api/[controller]")]
[ApiController]
public class WeatherController : ControllerBase
{
	[HttpPost]
	public IActionResult Post([FromForm] Weather weather)
	{
		SaveToDatabase(weather);

		return Ok();
	}
	
	//rest of class
}
Code language: C# (cs)

Questo mappa i dati del modulo alla classe Weather, che ha la seguente definizione:

using System.ComponentModel.DataAnnotations;

public class Weather
{
	[Required]
	public string Location { get; set; }

	public string Description { get; set; }

	[Required]
	[Range(-200, 200)]
	public int Temperature { get; set; }
}
Code language: C# (cs)

Le richieste a questo endpoint sarebbero simili a questa:

POST /api/weather HTTP/1.1
Content-Type: application/x-www-form-urlencoded

location=United+States&temperature=64&description=cloudyCode language: plaintext (plaintext)

Quando si esegue il mapping a un modello, abbina le chiavi del modulo ai nomi delle proprietà del modello. Come puoi vedere, esegue un confronto senza distinzione tra maiuscole e minuscole (posizione corrisponde a Meteo.Posizione ).

Errori di convalida della mappatura

Quando associa i dati del modulo ai parametri, esegue la convalida e restituisce una risposta di errore 400 – Richiesta non valida se c'è un problema.

Ad esempio, se c'è una mancata corrispondenza del tipo, riceverai una risposta di errore come questa:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-64ab197a56446c448095e9d3c3082c8b-a4255f612fce2e49-00",
    "errors": {
        "Temperature": [
            "The value 'text' is not valid for Temperature."
        ]
    }
}
Code language: JSON / JSON with Comments (json)

Se stai mappando su un modello, verrà convalidato anche rispetto agli attributi System.ComponentModel.DataAttributions.

Ad esempio, Weather.Location ha l'attributo [Obbligatorio]. Quando una proprietà richiesta non è presente nei dati del modulo, riceverai un errore come questo:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-d37111fc22168f42b5cbe4684eea9359-7a98c6fa7d623b4e-00",
    "errors": {
        "Location": [
            "The Location field is required."
        ]
    }
}Code language: JSON / JSON with Comments (json)

Risposta errore 415 – Tipo di supporto non supportato

Quando provi a mappare un modello e non includi l'attributo [FromForm], in questo modo:

[HttpPost]
public IActionResult Post(Weather weather)
Code language: C# (cs)

Quindi riceverai una risposta di errore 415 – Tipo di supporto non supportato .

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
    "title": "Unsupported Media Type",
    "status": 415,
    "traceId": "00-cac8e6fd75525e40b3e2b61e0bc2008a-725c6cba45bde44d-00"
}
Code language: JSON / JSON with Comments (json)

Questo problema può essere risolto aggiungendo l'attributo [FromForm]:

[HttpPost]
public IActionResult Post([FromForm] Weather weather)
Code language: C# (cs)

Leggi i dati del modulo senza mappare

Potrebbero esserci scenari in cui desideri leggere i dati del modulo senza che il framework lo configuri per te.

Puoi leggere i dati del modulo direttamente da HttpContext.Request.Form:

[HttpPost]
public IActionResult Post()
{
	foreach(var key in HttpContext.Request.Form.Keys)
	{
		var val = HttpContext.Request.Form[key];

		//process the form data
	}
	
	return Ok();
}
Code language: C# (cs)