ASP.NET Core:obtenga datos de formulario publicados en un controlador API

 C Programming >> Programación C >  >> Tags >> API
ASP.NET Core:obtenga datos de formulario publicados en un controlador API

Para obtener datos de formulario publicados en un controlador API (usando el atributo [ApiController]) en ASP.NET Core, use parámetros con el atributo [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 solicitud a este punto final se vería así:

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

location=United+StatesCode language: plaintext (plaintext)

Los datos del formulario son una cadena de pares clave-valor (por ejemplo:ubicación=Estados+Unidos ). El marco intenta asignar los datos del formulario a los parámetros haciendo coincidir las claves del formulario con los nombres de los parámetros (o los nombres de las propiedades del modelo).

Puede asignar varios campos de formulario como parámetros individuales, asignar a un modelo y también leer los datos del formulario directamente si lo desea. En este artículo, mostraré ejemplos de cada uno de estos escenarios.

Asignar varios campos de formulario como parámetros individuales

Digamos que su formulario tiene dos campos:Ubicación y Temperatura. Puede asignar estos campos como parámetros individuales:

[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)

Así es como se vería una solicitud a este punto final:

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

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

Nota:cuando hay varios campos de formulario, los pares clave-valor se separan con un ampersand (&).

Asignación a un modelo

En lugar de asignar campos de formulario como parámetros individuales, puede asignarlos a un modelo. Esta es una buena opción porque valida el modelo.

[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)

Esto asigna los datos del formulario a la clase Weather, que tiene la siguiente definición:

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)

Las solicitudes a este punto final se verían así:

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

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

Cuando se asigna a un modelo, hace coincidir las claves del formulario con los nombres de las propiedades del modelo. Como puede ver, hace una comparación que no distingue entre mayúsculas y minúsculas (ubicación coincide con Tiempo.Ubicación ).

Errores de validación de mapeo

Cuando asigna datos de formulario a parámetros, realiza la validación y devuelve la respuesta de error 400 – Solicitud incorrecta si hay un problema.

Por ejemplo, si hay una discrepancia de tipo, obtendrá una respuesta de error como esta:

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

Si está asignando a un modelo, también se validará con los atributos System.ComponentModel.DataAttributions.

Por ejemplo, Weather.Location tiene el atributo [Obligatorio]. Cuando falta una propiedad requerida en los datos del formulario, obtendrá un error como este:

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

Respuesta de error 415:tipo de medio no compatible

Cuando intenta mapear a un modelo y no incluye el atributo [FromForm], así:

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

Entonces obtendrá la respuesta de error 415 – Tipo de medio no admitido .

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

Esto se puede solucionar agregando el atributo [FromForm]:

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

Leer datos de formulario sin mapear

Puede haber escenarios en los que desee leer los datos del formulario sin que el marco lo asigne por usted.

Puede leer los datos del formulario directamente desde 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)