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();
}
}
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:
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!