Motivação

O redirecionamento entre URLs é essencial para o funcionamento de uma aplicação web. Diante disso, precisamos saber como e quando utilizá-lo, para que não haja uso excessivo desse recurso, uma vez que muitos redirecionamentos podem gerar erros no servidor. Nesse artigo, aprenderemos como fazer redirecionamentos dentro do ASP.NET MVC, tanto para URLs externas como para rotas internas, isto é, da própria aplicação.

Redirecionamento interno a um Action Method

Action method é um termo bastante comum no ASP.NET MVC. Os métodos de ação, em uma tradução literal, são, basicamente, ações que ocorrem dentro da aplicação web, podendo ou não representar uma página. Nesse contexto, o MVC trabalha com o conceito de que não há uma correspondência entre arquivos e/ou métodos com páginas web. Logo, cada aplicação possui sua estrutura. Na Figura 1 temos a comparação entre uma aplicação normal, com WebForms, por exemplo, e outra com MVC. Nota-se que, no WebForms e similares, a requisição é feita às páginas: assim, cada uma delas compõe um arquivo diferente. Já no MVC, os métodos de ação implementados nos controllers são utilizados para qualquer ação executada no website.

Exemplo de slider
Figura 1. Estrutura de uma aplicação ASP.NET MVC

Nessa estrutura, o redirecionamento possui suas próprias nuances. Isso faz com que, internamente, ele precise passar pelo mesmo caminho (Controller -> action method -> view), o que é diferente de redirecionarmos a aplicação para outra página. Dessa forma, redirecionamos para uma ação. Na Listagem 1, temos um método de edição – Edit() – através do qual realizamos o update das informações na base de dados e somos redirecionados para a página inicial – o action method Index.


01 [HttpPost]
02 public ActionResult Edit(Entity entity)
03 {      
04    _repository.Update(entity);
05    return RedirectToAction("Index");
06 }  
Listagem 1. Exemplo de uso do método RedirectToAction()

Linha 01: Atributo do método de ação que indica que se trata de uma requisição a ser feita através do verbo POST. Esse verbo é indicado quando temos alguma alteração a realizar no servidor;

Linha 02: Assinatura do método de ação Edit(). Nota-se que o mesmo recebe um valor do tipo Entity, uma entidade presente no repositório de dados(_repository);

Linha 04: Operação realizada na base de dados (Update()). Nesse caso, há o conceito de repositório de dados, como podemos observar pela variável _repository, e estamos simplesmente enviando a entidade a ele, que fará as operações necessárias para a atualização;

Linha 05: Nesse código acontece o redirecionamento propriamente dito. O método RedirectToAction() redireciona a aplicação a um action method dentro do mesmo controller com o nome Index. É importante notar que esse método aceita outros argumentos, como o nome do controller. Assim, caso você deseje redirecionar a aplicação para o método List() do ClientsController, por exemplo, teríamos um código como o apresentado abaixo:

return RedirectToAction("List", "Clients");

Redirecionamento interno a uma rota

Outra forma de redirecionamento interno em uma aplicação ASP.NET MVC é através dos dados da rota. O sistema de roteamento do MVC é baseado no mapeamento das rotas através de parâmetros, como mostra a Listagem 2. Esse sistema possibilita, portanto, fazer o redirecionamento através das próprias rotas ou de um objeto com parâmetros que se encaixem nas rotas - existem assinaturas do método para ambas as ações. Dessa forma, internamente o MVC opera um caminho à URL quando temos, por exemplo, uma rota que define o Controller, a Action e um parâmetro Id, como a rota padrão, que está presente no template do MVC, mostrada no código da Listagem 2.


01 routes.MapRoute(
02    name: "Default",
03    url: "{controller}/{action}/{id}",
04    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
05 );  
Listagem 2. Rota padrão no ASP.NET MVC

Linha 01: Adiciona a rota mapeada à coleção de rotas da aplicação;

Linhas 02 a 04: Definição das informações da rota que será mapeada pelo MVC. O nome dela (name), a URL que a define e os valores padrão (defaults). Podemos observar que temos uma rota com três parâmetros: o nome do controller, o nome do método de ação e o Id, que é um parâmetro opcional.

É importante notar que o método RedirectToRoute() não age em cima de uma simples rota, a não ser que o mandemos fazer isso. Normalmente, o MVC vai pegar os dados passados ao método e identificar em qual rota eles se encaixam, fazendo então o redirecionamento.

Um exemplo clássico da utilização desse método é mostrado no código abaixo. Nele, temos um redirecionamento ao método de ação Edit() do ClientsController, passando o id = 1. Tal rota normalmente abriria uma tela de edição para o cliente com Id igual a 1. Esses dados, ou route values, serão mapeados para a rota padrão mostrada na Listagem 2.

return RedirectToRoute(new { controller = "Clients", action = "Edit", id = 1 });

É válido observar que o mesmo comportamento poderia ser atingido com o método RedirectToAction(), e vice-versa. Acaba sendo uma questão de escolha, sempre tendo em mente que quando redirecionamos para uma rota muito específica, com vários parâmetros, o método RedirectToRoute() é uma melhor opção.

Redirecionamento externo (ou interno) a uma URL específica

Essa forma de redirecionamento é a mais simples de todas, uma vez que não utiliza nenhum conceito do ASP.NET MVC propriamente dito. O método Redirect() simplesmente leva a aplicação para uma URL qualquer, podendo ela ser externa ao website ou interna. No caso de redirecionamento interno, vale dar preferência aos métodos vistos anteriormente, que funcionam de forma mais confiável.

Um caso comum de redirecionamento a uma URL específica é verificado quando temos um conteúdo externo em nossa aplicação. Um link de propaganda, por exemplo, fará um redirecionamento para algo que não está no domínio interno. Outro exemplo é a utilização de algum tipo de login externo, embora, é claro, haja outros conceitos envolvidos nesse tipo de ação.

Na prática, o método mostrado na Listagem 3 faz uso do redirecionamento externo. Note que, primeiro, estamos contando o número de cliques no link, internamente, e então indo para a URL externa. Isso é útil para sabermos se as ações de marketing de um website estão funcionando, por exemplo.


01 public ActionResult OpenExternalLink(int idLink)
02 {
03     _repository.IncrementLinkCount(idLink);
04     return Redirect("http://devmedia.com.br");
05 } 
  
Listagem 3. Exemplo com o método Redirect(), utilizado com uma URL externa.

Linha 01: Definição do método de ação OpenExternalLink();

Linha 03: Ação do método. Nesse caso, há apenas o incremento na contagem de cliques do link selecionado;

Linha 04: O redirecionamento propriamente dito. Nesse caso, a aplicação será redirecionada à página inicial da DevMedia.

Redirecionamento permanente

Os três métodos mostrados até o momento também possuem suas “versões permanentes”: RedirectToActionPermanent(), RedirectToRoutePermanent() e RedirectPermanent(). A diferença entre os três métodos e suas versões "não permanentes" é bastante sutil, sendo mais conceitual do que prática.

Os navegadores trabalham com requisições e respostas a elas, e isso é realizado através de códigos de status. No caso dos métodos que não são permanentes, a aplicação MVC envia um código HTTP 302 ao navegador. Assim, ele irá entender que se trata de um redirecionamento simples e que é possível retornarmos à URL original. Já no caso dos redirecionamentos permanentes, o código enviado é o HTTP 301, que indica um movimento permanente. Nesses casos, o navegador normalmente irá guardar, em cache, a resposta e não enviará novas requisições à URL de origem automaticamente. Isso não significa que a aplicação não possa entrar novamente na página, caso ela exista: o navegador apenas age como se isso não fosse acontecer.

Para entendermos melhor esse conceito, voltemos à Listagem 1. No caso mostrado nela, temos uma edição de dados: é razoável presumirmos que o usuário pode voltar a ela para editar novamente o dado. Logo, o método RedirectToAction() (não permanente) está bem empregado. Agora, analisemos o código da Listagem 4. O código em si é similar. A diferença está na ação realizada: uma remoção.


01 [HttpPost]
02 public ActionResult Remove(Entity entity)
03 {      
04    _repository.Remove(entity);
05    return RedirectToActionPermanent("Index");
06 }
  
Listagem 4. Exemplo de uso do método RedirectToActionPermanent()

Linhas 01 e 02: Definição do atributo indicando que é um método POST e assinatura do método de ação Remove();

Linha 04: Ação realizada no repositório de dados para remoção da entidade;

Linha 05: Redirecionamento permanente para o action method Index(). Como temos uma remoção do dado, é válido presumirmos que não mais retornaremos à URL em questão. Por isso, a utilização do método de redirecionamento permanente é uma boa opção nesse caso.

Com esses exemplos, tivemos uma boa noção de como funcionam os redirecionamentos dentro do ASP.NET MVC e aprendemos como e quando devemos empregar cada um deles. Por fim, lembre-se que é preciso ter cuidado ao optar pelo redirecionamento permanente, uma vez que requisições desse tipo normalmente são mais custosas, devido ao salvamento dos dados da requisição em cache.