I'm procurando a maneira correta de retornar JSON com um código de status HTTP no meu controlador .NET Core Web API. Eu uso para usá-lo assim:
public IHttpActionResult GetResourceData()
{
return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}
Isto estava em uma aplicação 4.6 MVC mas agora com .NET Core I don't seem to have this IHttpActionResult
I have ActionResult
and using like this:
public ActionResult IsAuthenticated()
{
return Ok(Json("123"));
}
Mas a resposta do servidor é estranha, como na imagem abaixo:
Eu só quero que o controlador Web API retorne JSON com um código de status HTTP, como eu fiz na Web API 2.
A versão mais básica respondendo com um JsonResultado
é:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
No entanto, isto é'não vai ajudar no seu problema porque você pode'não lidar explicitamente com o seu próprio código de resposta.
A maneira de obter controle sobre os resultados do status, é você precisar retornar um
ActionResultado de Ação
que é onde você pode então tirar vantagem do tipo `StatusCodeResultado de Status'.
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 ambos os exemplos acima vieram de um grande guia disponível na Documentação da Microsoft: Formatação de Dados de Resposta
O problema com o qual me deparo com bastante frequência é que eu queria um controle mais granular sobre o meu WebAPI, em vez de apenas ir com a configuração padrão do "New Project" template em VS.
Deixem's ter a certeza que têm algumas das noções básicas...
Para que seu ASP.NET Core WebAPI responda com um Objeto Serializado JSON ao longo do controle total do código de status, você deve começar certificando-se de ter incluído o serviço AddMvc()
no seu método ConfigureServices' normalmente encontrado em
Startup.cs'.
It's importante notar que
AddMvc()
irá incluir automaticamente o Formato de Entrada/Saída para o JSON juntamente com a resposta a outros tipos de pedidos.
Se o seu projeto requer controle total e você deseja definir estritamente seus serviços, como por exemplo, como seu WebAPI irá se comportar com vários tipos de solicitação, incluindo aplicação/json
e não responder a outros tipos de solicitação (como uma solicitação padrão de navegador), você pode defini-la manualmente com o seguinte 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)
}
Você notará que eu também incluí uma forma de você adicionar seus próprios formatadores de Entrada/Saída personalizados, caso você queira responder a outro formato de serialização (protobuf, thrift, etc).
O trecho de código acima é, em sua maioria, uma duplicação do método AddMvc()
. Entretanto, estamos implementando cada "default" serviço por conta própria, definindo cada serviço em vez de ir com o pré-enviado com o template. Eu adicionei o link do repositório no bloco de código, ou você pode verificar AddMvc()
do repositório GitHub..
Note que existem alguns guias que tentarão resolver isto por "desfazer" os incumprimentos, em vez de simplesmente não o implementar em primeiro lugar... Se você considerar que nós'estamos agora trabalhando com Código Aberto, isso é trabalho redundante, código ruim e francamente um velho hábito que vai desaparecer em breve.
I'vou mostrar-lhe uma muito directa só para esclarecer a sua questão.
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();
}
}
Content-Type
e Accept
Você precisa ter certeza de que os cabeçalhos "Tipo de Conteúdo" e "Aceitar" no seu request estão definidos corretamente. No seu caso (JSON), você vai querer configurá-lo para ser aplicação/json
.
Se você quiser que seu WebAPI responda como JSON como padrão, independentemente do que o cabeçalho da solicitação estiver especificando, você pode fazer isso de uma forma couple.
**Caminho 1*** Como mostrado no artigo que recomendei anteriormente (Formatting Response Data) você pode forçar um determinado formato no nível Controlador/Ação. Eu pessoalmente não'não gosto desta abordagem... mas aqui está para a completude:
Forçando um formato particular Se você quiser restringir os formatos de resposta para uma ação específica, você pode aplicar o [Produz] filtro. O filtro [Produz] especifica a resposta formatos para uma ação específica (ou controlador). Como a maioria dos Filtros, este pode ser aplicado na ação, no controlador ou em âmbito global.
[Produz(" aplicação/json")]
classe pública AuthorsController
O filtro
[Produz]
forçará todas as ações dentro doAuthorsController
para devolver respostas em formato JSON, mesmo que outras os formatadores foram configurados para a aplicação e o cliente forneceu um cabeçalho `Accept' solicitando um formato diferente, disponível.
Way 2 O meu método preferido é que a WebAPI responda a todos os pedidos com o formato solicitado. Contudo, caso não aceite o formato pedido, então fall-back para um formato padrão (ou seja, JSON)
Primeiro, você'precisará registrar isso em suas opções (precisamos retrabalhar o comportamento padrão, como observado anteriormente)
options.RespectBrowserAcceptHeader = true; // false by default
Finalmente, ao simplesmente reordenar a lista de formatadores que foram definidos no construtor de serviços, o anfitrião web irá por defeito para o formatador que você posicionar no topo da lista (ou seja, posição 0).
Mais informações podem ser encontradas neste .NET Web Development and Tools Blog entry
Você tem métodos predefinidos para os códigos de status mais comuns.
Ok(resultado)
devolve 200
com resposta201
+ novo URL do recursoVeja BaseController.cs
e Controller.cs
para uma lista de todos os métodos.
Mas se você realmente insiste que você pode usar StatusCode
para definir um código personalizado, mas você realmente deven't como ele torna o código menos legível e você'terá que repetir o código para definir cabeçalhos (como para CreatedAtRoute
).
public ActionResult IsAuthenticated()
{
return StatusCode(200, "123");
}
Por favor, consulte o código abaixo, Você pode gerenciar vários códigos de status com diferentes tipos JSON
public async Task<HttpResponseMessage> GetAsync()
{
try
{
using (var entities = new DbEntities())
{
var resourceModelList = entities.Resources.Select(r=> new ResourceModel{Build Your Resource Model}).ToList();
if (resourceModelList.Count == 0)
{
return this.Request.CreateResponse<string>(HttpStatusCode.NotFound, "No resources found.");
}
return this.Request.CreateResponse<List<ResourceModel>>(HttpStatusCode.OK, resourceModelList, "application/json");
}
}
catch (Exception ex)
{
return this.Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "Something went wrong.");
}
}