La versión más básica que responde con un JsonResult
es:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
Sin embargo, esto no ayudará con su problema porque no puede manejar explícitamente su propio código de respuesta.
La forma de obtener el control sobre los resultados de estado es que debe devolver uno ActionResult
que es donde puede aprovechar el StatusCodeResult
tipo.
por ejemplo:
// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authorRepository.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
Tenga en cuenta que ambos ejemplos anteriores provienen de una excelente guía disponible de la documentación de Microsoft: Formateo de datos de respuesta
Cosas extra
El problema que encuentro con bastante frecuencia es que quería un control más granular sobre mi WebAPI en lugar de simplemente ir con la configuración predeterminada de la plantilla "Nuevo proyecto" en VS.
Asegurémonos de tener algunos de los conceptos básicos ...
Paso 1: configura tu servicio
Para que su ASP.NET Core WebAPI responda con un objeto serializado JSON junto con el control total del código de estado, debe comenzar asegurándose de haber incluido el AddMvc()
servicio en su ConfigureServices
método que generalmente se encuentra en Startup.cs
.
Es importante tener en cuenta que AddMvc()
incluirá automáticamente el formateador de entrada / salida para JSON junto con la respuesta a otros tipos de solicitud.
Si su proyecto requiere control total y desea definir estrictamente sus servicios, por ejemplo, cómo se comportará su WebAPI frente a varios tipos de solicitud, incluidos application/json
y no responder a otros tipos de solicitud (como una solicitud de navegador estándar), puede definirlo manualmente con el siguiente código:
public void ConfigureServices(IServiceCollection services)
{
// Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
// https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs
services
.AddMvcCore(options =>
{
options.RequireHttpsPermanent = true; // does not affect api requests
options.RespectBrowserAcceptHeader = true; // false by default
//options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
//remove these two below, but added so you know where to place them...
options.OutputFormatters.Add(new YourCustomOutputFormatter());
options.InputFormatters.Add(new YourCustomInputFormatter());
})
//.AddApiExplorer()
//.AddAuthorization()
.AddFormatterMappings()
//.AddCacheTagHelper()
//.AddDataAnnotations()
//.AddCors()
.AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}
Notarás que también he incluido una forma para que agregues tus propios formateadores de entrada / salida personalizados, en el caso de que quieras responder a otro formato de serialización (protobuf, ahorro, etc.).
El fragmento de código anterior es principalmente un duplicado del AddMvc()
método. Sin embargo, estamos implementando cada servicio "predeterminado" por nuestra cuenta definiendo todos y cada uno de los servicios en lugar de ir con el preenviado con la plantilla. He agregado el enlace del repositorio en el bloque de código, o puede consultarlo AddMvc()
desde el repositorio de GitHub. .
Tenga en cuenta que hay algunas guías que tratarán de resolver esto "deshaciendo" los valores predeterminados, en lugar de simplemente no implementarlo en primer lugar ... Si considera que ahora estamos trabajando con Open Source, este es un trabajo redundante , mal código y, francamente, un viejo hábito que desaparecerá pronto.
Paso 2: crear un controlador
Te voy a mostrar una muy sencilla para resolver tu pregunta.
public class FooController
{
[HttpPost]
public async Task<IActionResult> Create([FromBody] Object item)
{
if (item == null) return BadRequest();
var newItem = new Object(); // create the object to return
if (newItem != null) return Ok(newItem);
else return NotFound();
}
}
Paso 3: comprueba tu Content-Type
yAccept
Debe asegurarse de que su Content-Type
y los Accept
encabezados en su solicitud estén configurados correctamente. En su caso (JSON), querrá configurarlo para que sea application/json
.
Si desea que su WebAPI responda como JSON de forma predeterminada, independientemente de lo que especifique el encabezado de la solicitud, puede hacerlo de dos maneras .
Forma 1
Como se muestra en el artículo que recomendé anteriormente ( Formatear datos de respuesta ), podría forzar un formato particular en el nivel Controlador / Acción. Personalmente no me gusta este enfoque ... pero aquí está para completar:
Forzar un formato particular Si desea restringir los formatos de respuesta para una acción específica, puede aplicar el filtro [Produce]. El filtro [Produce] especifica los formatos de respuesta para una acción específica (o controlador). Como la mayoría de los filtros, esto se puede aplicar en la acción, el controlador o el alcance global.
[Produces("application/json")]
public class AuthorsController
El [Produces]
filtro forzará todas las acciones dentro del
AuthorsController
para devolver respuestas con formato JSON, incluso si se configuraron otros formateadores para la aplicación y el cliente proporcionó un Accept
encabezado solicitando un formato diferente y disponible.
Modo 2
Mi método preferido es que WebAPI responda a todas las solicitudes con el formato solicitado. Sin embargo, en el caso de que no acepte el formato solicitado, recurra a un valor predeterminado (es decir, JSON)
Primero, deberá registrar eso en sus opciones (necesitamos modificar el comportamiento predeterminado, como se señaló anteriormente)
options.RespectBrowserAcceptHeader = true; // false by default
Finalmente, simplemente reordenando la lista de los formateadores que se definieron en el creador de servicios, el proveedor de alojamiento web adoptará el formateador que coloque en la parte superior de la lista (es decir, la posición 0).
Se puede encontrar más información en esta entrada de Blog de herramientas y desarrollo web .NET
CreatedAtRoute
el método etc