ASP.NET MVC Action Results

Em geral, quando um controller recebe uma requisição e a processa, ele gera algum tipo de resultado para o usuário. Este resultado pode ser uma view, um redirecionamento HTTP, texto em formato XML ou JSON, entre outros.

Tudo isso poderia ser feito diretamente na action de um controller, como abaixo:

public void Index()
{
   Response.Write("<b>Hello, World!</b>");
   // outro exemplo:
   Response.Redirect("/AlgumaUrl");
}

No entanto, a solução acima não é uma boa prática, uma vez que ela mistura geração de html com a lógica da aplicação prejudicando, assim, a SoC (separation of concerns). Além disso, essa solução dificulta a realização de testes de unidade, uma vez que seria preciso “mockar” o objeto Response.

Para resolver esses problemas, o ASP.NET MVC disponibiliza os action results, objetos derivados da classe base ActionResult, responsáveis por “montar” o resultado pretendido, eliminando essa responsabilidade do controller e garantindo, assim, sua melhor organização.

Veja como ficaria o exemplo acima:

public ViewResult Index()
{
   // renderiza uma view com o conteudo desejado ao inves de produzi-lo diretamente dentro da action
   return View();
}

O framework oferece uma série de action results para produzir os mais variados resultados. Vejamos alguns exemplos:

1) Retornando uma view fortemente tipada

public ViewResult ExibirDetalhesDoCliente()
{
   var cliente = new Cliente { Nome = "ROBSON", CPF = "99999999999" };
   return View(cliente);
}

O código acima atribui implicitamente o objeto ‘cliente’ à propriedade ViewData.Model, podendo ser acessada na view assim:

Cliente: @Model.Nome, CPF: @Model.CPF

“Model” nada mais é do que um modo mais curto de referenciar ViewData.Model pela view. No entanto, em uma action do controller ainda é preciso referenciar o objeto como ViewData.Model.

2) Retornando uma view com um objeto dinâmico

É possível também utilizar o recurso de linguagem dinâmica do .NET 4.0, retornando para a view um objeto criado em runtime. Veja como fica:

public ViewResult ExibirDetalhesDoCliente()
{
   dynamic objetoDinamico = new ExpandoObject();
   objetoDinamico.QualquerCoisa = "123";
   objetoDinamico.OutraCoisa = new Cliente { Nome = "ROBSON", CPF = "99999999999" };
   return View(objetoDinamico);
}

Na view, teríamos o seguinte:

@Model.QualquerCoisa
<br/>
@Model.OutraCoisa.Nome

O problema da abordagem acima é que, assim como utilizar ViewData[“qualquercoisa”], não temos um objeto fortemente tipado, podendo ocorrer erro em runtime caso o nome de alguma propriedade seja digitado incorretamente (além de não possuirmos ajuda do Intellisense).

3) Redirecionando para outra action:

public RedirectToRouteResult Salvar()
{
   // faz alguma coisa aqui
   // e redireciona para a action Index
   return RedirectToAction("Index");
}

No código acima, será enviado ao browser o status code HTTP 302, fazendo com que o browser execute uma nova requisição GET para “/NomeDoController/Index”, alterando a URL exibida na barra de endereço.

4) Redirecionando para uma URL:

public RedirectResult MeuBlog()
{
   return Redirect("https://robsoncastilho.wordpress.com");
}

5) Retornando um objeto JSON:

[HttpPost]
public JsonResult ListaDeCidades()
{
    var cidades = new List<Cidade>
                     {
                         new Cidade { Nome = "CAMPO GRANDE" },
                         new Cidade { Nome = "DOURADOS" }
                     };
    return Json(cidades);
}

6) Retornando um arquivo do disco:

public FileResult Download()
{
   var arquivo = @"C:\arquivo.pdf";
   return File(arquivo, "application/pdf", "Relatorio.pdf");
}

Vejam, nos exemplos acima, que cada action declara seu tipo de retorno para o tipo mais específico de ActionResult, tais como ViewResult, RedirectToRouteResult, RedirectResult, JsonResult e FileResult. Embora todas as actions pudessem declarar como retorno a classe base ActionResult, ainda é uma boa prática explicitar o tipo mais específico.

Uma tabela completa de action results pode ser encontrada [aqui]. Além disso, é possível criar sua própria action result, derivando de uma action result existente ou ainda da classe base ActionResult. Veremos isso em algum post no futuro.

Conclusão

As action results são responsáveis pela montagem da resposta de uma action, seja ela uma view, um redirecionamento, um json, um arquivo binário, retirando essa responsabilidade do controller e garantindo melhor separação de responsabilidades (SoC) e testabilidade.

Sendo assim, evite utilizar o objeto Response diretamente em seus action methods. Deixe que a action result cuide disso!

6 comentários em “ASP.NET MVC Action Results

Adicione o seu

Participe! Vamos trocar uma ideia sobre desenvolvimento de software!

Blog no WordPress.com.

Acima ↑