A versão mais básica que responde com a JsonResult
é:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
No entanto, isso não ajudará no seu problema, porque você não pode lidar explicitamente com seu próprio código de resposta.
A maneira de obter controle sobre os resultados do status é retornar um ActionResult
que é onde você pode tirar proveito do StatusCodeResult
tipo.
por exemplo:
// 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);
}
Observe que os dois exemplos acima vieram de um ótimo guia disponível em Documentação da Microsoft: Formatando dados de resposta
Coisas extras
O problema que me deparo com frequência é que eu queria um controle mais granular sobre minha WebAPI, em vez de apenas ir com a configuração de padrões do modelo "New Project" no VS.
Vamos garantir que você tenha alguns princípios básicos ...
Etapa 1: configurar seu serviço
Para que sua ASP.NET Core WebAPI responda com um Objeto serializado JSON ao longo do controle total do código de status, você deve começar por incluir o AddMvc()
serviço em seu ConfigureServices
método normalmente encontrado em Startup.cs
.
É importante observar que AddMvc()
incluirá automaticamente o Formatador de Entrada / Saída para JSON, além de responder a outros tipos de solicitação.
Se seu projeto requer controle total e você deseja definir estritamente seus serviços, como o comportamento da sua WebAPI com vários tipos de solicitação, incluindo application/json
e não respondendo a outros tipos de solicitação (como uma solicitação padrão do navegador), você pode defini-lo manualmente com o código a seguir:
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)
}
Você notará que eu também incluí uma maneira de adicionar seus próprios formatadores de entrada / saída personalizados, caso você queira responder a outro formato de serialização (protobuf, thrift etc.).
O pedaço de código acima é basicamente uma duplicata do AddMvc()
método. No entanto, estamos implementando cada serviço "padrão" por conta própria, definindo cada serviço em vez de ir com o serviço pré-enviado com o modelo. Eu adicionei o link do repositório no bloco de código, ou você pode fazer o check-out AddMvc()
no repositório do GitHub. .
Observe que existem alguns guias que tentarão resolver isso "desfazendo" os padrões, em vez de simplesmente não implementá-lo ... Se você considerar que agora estamos trabalhando com código aberto, este é um trabalho redundante , código ruim e francamente um velho hábito que desaparecerá em breve.
Etapa 2: Criar um Controlador
Vou mostrar uma pergunta realmente direta apenas para esclarecer sua dúvida.
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();
}
}
Etapa 3: verifique seu Content-Type
eAccept
Você precisa garantir que seus cabeçalhos Content-Type
e os de Accept
sua solicitação estejam definidos corretamente. No seu caso (JSON), você desejará configurá-lo para ser application/json
.
Se você deseja que sua WebAPI responda como JSON como padrão, independentemente do que o cabeçalho da solicitação está especificando, você pode fazer isso de duas maneiras .
Caminho 1
Como mostrado no artigo que eu recomendei anteriormente ( Formatação de dados de resposta ), você pode forçar um formato específico no nível do controlador / ação. Pessoalmente, não gosto dessa abordagem ... mas aqui está a questão:
Forçando um formato específico Se você deseja restringir os formatos de resposta para uma ação específica, pode aplicar o filtro [Produces]. O filtro [Produces] especifica os formatos de resposta para uma ação específica (ou controlador). Como a maioria dos filtros, isso pode ser aplicado no escopo de ação, controlador ou global.
[Produces("application/json")]
public class AuthorsController
O [Produces]
filtro forçará todas as ações no
AuthorsController
retorno a respostas formatadas em JSON, mesmo se outros formatadores foram configurados para o aplicativo e o cliente forneceu um Accept
cabeçalho solicitando um formato disponível diferente.
Caminho 2
Meu método preferido é o WebAPI responder a todas as solicitações com o formato solicitado. No entanto, caso ele não aceite o formato solicitado, retorne ao padrão (por exemplo, JSON)
Primeiro, você precisará registrar isso em suas opções (precisamos refazer o comportamento padrão, conforme observado anteriormente)
options.RespectBrowserAcceptHeader = true; // false by default
Por fim, simplesmente reordenando a lista dos formatadores que foram definidos no construtor de serviços, o host padrão será o formatador que você posicionar no topo da lista (ou seja, posição 0).
Mais informações podem ser encontradas nesta entrada do blog .NET Web Development and Tools
CreatedAtRoute
método etc.