Partilhar via


Tratar pedidos com controladores no ASP.NET Core MVC

Por Steve Smith e Scott Addie

Controladores, ações e resultados de ações são uma parte fundamental da forma como os programadores constroem aplicações usando ASP.NET Core MVC.

O que é um Controlador?

Um controlador é usado para definir e agrupar um conjunto de ações. Uma ação (ou método de ação) é um método num controlador que gere pedidos. Os controladores agrupam logicamente ações semelhantes. Esta agregação de ações permite que conjuntos comuns de regras, como encaminhamento, cache e autorização, sejam aplicados coletivamente. Os pedidos são mapeados para ações por meio de encaminhamento. Os controladores são ativados e eliminados por solicitação.

Por convenção, classes de controlador:

  • Reside na pasta Controllers ao nível raiz do projeto.
  • Herdar de Microsoft.AspNetCore.Mvc.Controller.

Um controlador é uma classe instanciaável, geralmente pública, na qual pelo menos uma das seguintes condições é verdadeira:

  • O nome da classe é sufixado com Controller.
  • A classe herda de uma classe cujo nome termina com Controller.
  • O [Controller] atributo é aplicado à classe.

Uma classe controlador não pode ter um atributo associado [NonController] .

Os controladores devem seguir o Princípio das Dependências Explícitas. Existem algumas abordagens para implementar este princípio. Se múltiplas ações de controlador requerem o mesmo serviço, considere usar injeção de construtor para solicitar essas dependências. Se o serviço for necessário apenas por um único método de ação, considere usar Injeção de Ação para requerer a dependência.

No padrão Model-View-Controller, um controlador é responsável pelo processamento inicial da requisição e instanciação do modelo. Geralmente, as decisões empresariais devem ser tomadas dentro do modelo.

O controlador recebe o resultado do processamento do modelo (se houver) e devolve ou a vista correta e os dados de visualização associados, ou o resultado da chamada API. Saiba mais na Visão Geral do ASP.NET Core MVC e comece com ASP.NET Core MVC e Visual Studio.

O controlador é uma abstração ao nível da UI. As suas responsabilidades são garantir que os dados da requisição são válidos e escolher qual vista (ou resultado de uma API) deve ser retornado. Em aplicações bem fatorizadas, não inclui diretamente acesso a dados ou lógica de negócio. Em vez disso, o controlador delega aos serviços que gerem essas responsabilidades.

Definindo Ações

Métodos públicos num controlador, exceto aqueles com o [NonAction] atributo, são ações. Os parâmetros das ações estão vinculados a pedir dados e são validados através de ligação de modelos. A validação do modelo ocorre para tudo o que está ligado ao modelo. O valor da ModelState.IsValid propriedade indica se a ligação e validação do modelo tiveram sucesso.

Os métodos de ação devem conter lógica para mapear uma requisição a uma questão de negócios. As preocupações empresariais devem normalmente ser representadas como serviços que o controlador acede através da injeção de dependências. As ações então mapeiam o resultado da ação empresarial para um estado da aplicação.

As ações podem devolver qualquer coisa, mas frequentemente retornam uma instância de IActionResult (ou Task<IActionResult> para métodos assíncronos) que produz uma resposta. O método de ação é responsável por escolher que tipo de resposta. O resultado da ação responde.

Métodos de Assistente de Controladores

Os controladores normalmente herdam de Controller, embora isso não seja obrigatório. Derivar de Controller proporciona acesso a três categorias de métodos auxiliares:

1. Métodos que resultam num corpo de resposta vazio

Não está incluído um cabeçalho de resposta HTTP Content-Type, pois o corpo da resposta não possui conteúdo para descrever.

Existem dois tipos de resultados dentro desta categoria: Redirecionar e Código de Estado HTTP.

  • Código de Estado HTTP

    Este tipo devolve um código de estado HTTP. Alguns métodos auxiliares deste tipo são BadRequest, NotFound, e Ok. Por exemplo, return BadRequest(); produz um código de estado 400 quando executado. Quando métodos como BadRequest, NotFound, e Ok estão sobrecarregados, deixam de qualificar-se como respondentes do Código de Estado HTTP, uma vez que está a decorrer negociação de conteúdo.

  • Redirecionamento

    Este tipo devolve um redirecionamento para uma ação ou destino (usando Redirect, LocalRedirect, RedirectToAction, ou RedirectToRoute). Por exemplo, return RedirectToAction("Complete", new {id = 123}); redireciona para Complete, passando um objeto anónimo.

    O tipo de resultado de Redirecionamento difere do tipo de Código de Estado HTTP principalmente pela adição de um Location cabeçalho de resposta HTTP.

2. Métodos que resultam num corpo de resposta não vazio com um tipo de conteúdo pré-definido

A maioria dos métodos auxiliares nesta categoria inclui uma ContentType propriedade, permitindo definir o Content-Type cabeçalho da resposta para descrever o corpo da resposta.

Existem dois tipos de resultados dentro desta categoria: Visualização e Resposta Formatada.

  • View

    Este tipo devolve uma vista que utiliza um modelo para renderizar HTML. Por exemplo, return View(customer); passa um modelo para a vista para associação de dados.

  • Resposta Formatada

    Este tipo devolve JSON ou um formato de troca de dados semelhante para representar um objeto de uma forma específica. Por exemplo, return Json(customer); serializa o objeto fornecido em formato JSON.

    Outros métodos comuns deste tipo incluem File e PhysicalFile. Por exemplo, return PhysicalFile(customerFilePath, "text/xml"); retorna PhysicalFileResult.

3. Métodos que resultam num corpo de resposta não vazio formatado num tipo de conteúdo negociado com o cliente

Esta categoria é mais conhecida como Negociação de Conteúdos. A negociação de conteúdo aplica-se sempre que uma ação devolve um ObjectResult tipo ou algo que não seja uma IActionResult implementação. Uma ação que retorna uma implementação não IActionResult (por exemplo, object) também retorna uma Resposta Formatada.

Alguns métodos auxiliares deste tipo incluem BadRequest, CreatedAtRoute, e Ok. Exemplos destes métodos incluem return BadRequest(modelState);, return CreatedAtRoute("routename", values, newobject);, e return Ok(value);, respetivamente. Note que BadRequest e Ok só realizam negociação de conteúdo quando lhes passa um valor; sem lhes passar um valor, servem antes como tipos de resultado do Código de Estado HTTP. O CreatedAtRoute método, por outro lado, realiza sempre negociação de conteúdo, pois todas as suas sobrecargas exigem que um valor seja passado.

Preocupações transversais

As aplicações normalmente partilham partes do seu fluxo de trabalho. Exemplos incluem uma aplicação que exige autenticação para aceder ao carrinho de compras, ou uma aplicação que armazena dados em cache em algumas páginas. Para executar lógica antes ou depois de um método de ação, use um filtro. O uso de filtros em questões de corte transversal pode reduzir a duplicação.

A maioria dos atributos do filtro, como [Authorize], pode ser aplicada ao nível do controlador ou da ação, dependendo do nível desejado de granularidade.

O tratamento de erros e a cache de respostas são frequentemente preocupações transversais:

Muitas preocupações transversais podem ser resolvidas usando filtros ou middleware personalizado.