Tabela de rotas – Parte 2

Segunda parte das explicações relativas à tabela de rotas de ASP.NET MVC, um componente básico que podemos configurar para personalizar totalmente as URLs das aplicações web.

Por Eduard Tomás - Tradução CRV


Publicado em: 14/9/11
Valorize este artigo:

Valores de rota e controladores

Vimos que há dois valores de rota (“controller” e “action”) que devem ser estabelecidos a partir de cada URL. Mas… o que ocorre com o resto de valores de rota que estabelecemos? (como p.ex. o “id” ou o “author" dos exemplos anteriores). Bem, simplesmente, esses valores são passados aos controladores, onde podem ser consultados de várias formas, sendo uma das mais comuns que estejam como parâmetros nas ações.

P.ex. no caso do valor de rota author, a ação View do controlador Profile poderia estar declarada tal como segue:

public class ProfileController : Controller
{
[ActionName("View")]
public ActionResult Ver(string author)
{
return View();
}
}

Nota: Neste caso usamos o atributo [ActionName] que permite indicar o nome da ação que implementa um método em concreto. Se não se usa esse atributo o nome da ação é o mesmo que o nome do método. Neste caso devemos usá-lo porque a ação se chama View, mas o nome de método View já está definido dentro da classe Controller (e é usado para retornar visões).
Podemos ver como a ação View recebe o parâmetro “author", cujo valor será valor de rota com o mesmo nome (autor). Ou seja, no caso da URL http://servidor/Ver/Edu o valor do parâmetro author será precisamente “Edu”.

No caso de parâmetros opcionais, a coisa é um pouquinho mais delicada. Suponhamos que temos a seguinte ação:

public class HomeController : Controller
{
public ActionResult Index(int i)
{
return View();
}
}

Suponhamos que esta ação foi mapeada a partir da entrada “Default” da tabela de rotas. Se entrarmos uma url do tipo http://servidor/Home/Index/10 não há problema porque o valor de “id” é 10. Porém, neste caso id é um parâmetro opcional. E o que acontece se entramos a URL http://servidor/Home/Index?

Lembrem que um parâmetro opcional, se não aparece simplesmente não é criado. Não é que valha 0, ou “” ou null. É que não se cria. Portanto, se entramos uma URL de tipo http://servidor/Home/Index receberemos um erro:

O erro indica que a ação espera um parâmetro (id) mas que não há valor de rota da qual tomar esse parâmetro. Se o parâmetro aceitasse null (ou seja , fosse um valor por referência como string) o framework atribuiria null a esse parâmetro e não se queixaria. Porém int não aceita null, assim que o framework dá esse erro.

É normal, no começo, pensar que para solucionar isto bastaria acrescentar, um método Index sem parâmetros ao controlador. Algo como:

public class HomeController : Controller
{
// URLs tipo /Home/Index/10
public ActionResult Index(int i)
{
return View();
}

// URLs tipo /Home/Index
public ActionResult Index()
{
return View();
}
}

Porém, se testarmos isto, vamos perceber que agora nos aparece outro erro diferente:

Além disso, esse erro aparece indistintamente, quer seja quando entramos http://servidor/Home/Index/10 (com id) ou com http://servidor/Home/Index (sem id).

A razão deste erro é muito simples: uma mesma ação só pode ser implementada por um único método (há uma exceção a este caso que é quando são usados verbos http diferentes, mas isso será visto em artigos posteriores). Neste caso, temos dois métodos (Index() e Index(int)) onde ambos implementam a ação Index. e isso não é permitido.

A solução para toda “essa bagunça” passa por fazer uma de duas coisas:

  1. Converter o parâmetro da ação para algo que aceite nulls (p.ex. string ou então int?).
  2. Ou modificar a tabela de rotas para que o parâmetro, em lugar de ser opcional, tenha um valor por padrão.
Se optarmos pelo primeiro caso, a ação pode ficar como:

public class HomeController : Controller
{
public ActionResult Index(int? id)
{
return View();
}
}

Agora, a URL http://servidor/Home/Index é roteada para esta ação e como o valor de rota id não existe, o método de ação receberá um null.

Por outro lado, a URL http://servidor/Home/Index/10 é roteada para esta mesma ação e o valor de rota id valerá 10 (e esse será o valor do parâmetro que receba o controlador).

Se optarmos por modificar a tabela de rotas, em lugar de declarar o valor de rota id como opcional, tal valor deve ter um valor por padrão:

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = 0} // Parameter defaults
);

Observem agora que o valor por padrão do valor de rota id é 0. Agora a URL http://servidor/Home/Index é roteada para a ação com o valor de rota id com valor 0. E por sua parte a URL http://servidor/Home/Index/20 é roteada para a mesma ação mas com o valor de rota id de 20.

Deve se notar que neste caso não se pode diferenciar entre a url http://servidor/Home/Index e a url http://servidor/Home/Index/0 (ambas URLs têm o valor de rota id com valor 0).

Assim, terminamos este artigo dedicado à tabela de rotas, um dos componentes básicos de ASP.NET MVC mas à qual muito pouca gente dá atenção, no começo!





Comentários do artigo
Foi enviado 1 comentário ao artigo
1 comentário não revisado
0 comentários revisados

Usuários :    login / registro

Manuais relacionados
Categorias relacionadas
O autor

Home | Sobre nós | Copyright | Anuncie | Entrar em contato