ASP.NET MVC

13

description

A explosão da Web nos últimos anos potenciou a introdução de plataformas que simplificam as tarefas de desenvolvimento das aplicações. Foi neste cenário que o padrão MVC voltou a ganhar vida, fazendo com que a Microsoft apostasse no lançamento de uma nova plataforma, designada por ASP.NET MVC, que foi desenvolvida a pensar na separação de responsabilidades e na construção de aplicações facilmente testadas. Esta obra foi escrita a pensar nos programadores que já têm alguma experiência no desenvolvimento de aplicações Web e que procuram obter o máximo de informação sobre o desenvolvimento em ASP.NET MVC. Contudo, é também essencial para todos os programadores ASP.NET Web Forms que procuram efetuar a transição dessa plataforma para o ASP.NET MVC. Ao longo do livro, encontramos informação detalhada e exemplos práticos que apresentam os principais blocos e componentes introduzidos pela última versão desta plataforma.

Transcript of ASP.NET MVC

Page 1: ASP.NET MVC
Page 2: ASP.NET MVC

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

222 1RROOTTEEAAMMEENNTTOO

O roteamento desempenha um papel importante na interceção e redireciona-

mento de pedidos HTTP para a plataforma ASP.NET MVC. Ao longo deste

capítulo, vamos analisar algumas das particularidades associadas ao roteamento

de pedidos em ASP.NET MVC.

2.1 UURRLL

Um URL (Uniform Resource Locator1) representa um endereço que identifica

univocamente um recurso numa determinada rede. Na prática, um URL segue

sempre uma estrutura do tipo protocolo://máquina/caminho/recurso. No caso das

aplicações Web, os URL foram usados durante anos para identificar recursos

existentes num servidor (por exemplo, o índice da especificação do HTML5 pode

ser obtida a partir de http://dev.w3.org/html5/spec/Overview.html).

O leitor com experiência no desenvolvimento de aplicações Web no

“universo” Microsoft recorda, com toda a certeza, o uso de URL do tipo

http://www.minhaempresa.com/filmes/lista.aspx?categoria=1. Nestes casos, era

quase certa a existência de uma página ASPX, designada por lista.aspx, que seria

responsável por tratar pedidos desse género, tendo em atenção o parâmetro

passado na query string. Ou seja, no mundo ASP.NET pré-MVC, era normal

existir um relacionamento direto entre um URL e um recurso físico (geralmente,

uma página ASPX ou uma handler) existente no disco. Com a introdução da

plataforma ASP.NET MVC, este relacionamento entre URL e recurso físico já não

existe, uma vez que o mapeamento passa a ser estabelecido entre um URL e um

1 Se quisermos ser precisos, um URL é um tipo concreto de URI (Uniform Resource Identifier). Contudo,

e na prática, ambos são muitas vezes usados como sinónimos. O leitor interessado pode obter mais detalhes em

http://bit.ly/TzQ7w.

Page 3: ASP.NET MVC

AASSPP..NNEETT MMVVCC

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

26

método de ação de um controlador (os métodos públicos de um controlador que

são responsáveis por tratar pedidos HTTP são designados por métodos de ação).

Por exemplo, no caso de aplicações ASP.NET MVC, é normal encon-

trarmos URL do tipo http://www.minhaempresa.com/filmes/categoria/1. Estes

URL são intercetados pela infraestrutura de roteamento, que se encarrega de os

redirecionar (indiretamente) para um método de ação de um controlador, que,

por sua vez, é responsável por gerar a resposta devolvida ao browser.

Note-se que esta forma de definir URL permite-nos ainda melhorar a

usabilidade2 associada aos URL de uma aplicação (se compararmos os dois URL

anteriores, rapidamente concluimos que o último é mais fácil de memorizar e

transmite mais informação acerca do recurso devolvido – estas são apenas duas

boas caraterísticas de um URL).

2.2 IINNTTRROODDUUÇÇÃÃOO AAOO RROOTTEEAAMMEENNTTOO

A plataforma ASP.NET recorre ao roteamento para atingir dois objetivos:

Mapear URL de pedidos HTTP em métodos de ação disponibilizados

por um controlador;

Gerar URL que, no futuro, produzam pedidos HTTP que sejam

mapeados num método de ação de um controlador.

Roteamento versus URL rewriting

O leitor com experiência no uso de URL rewriting pode ser tentado a ver o roteamento

como uma nova forma de efetuar a reescrita de URL (a reescrita de URL permite-nos criar

URL amigáveis que melhorem os resultados devolvidos pelos motores de pesquisa – esta

é uma das técnicas mais usadas nas otimizações SEO3). Existe, contudo, uma diferença

importante entre ambas as técnicas. O URL rewriting concentra-se apenas em transformar

um URL num outro URL. Por sua vez, o roteamento é responsável por mapear um URL

2 Jakob Nielsen (um guru do estudo da usabilidade) estudou a influência de URL na acessibilidade de

aplicações. O leitor interessado pode obter algumas recomendações sobre a geração destes identificadores em

http://bit.ly/9x0mm.

3 SEO (Search Engine Optimizations) descreve um processo para melhorar a visibilidade de links de sites

nas pesquisas efetuadas por motores de busca. O link http://bit.ly/1oIpqX efetua uma boa introdução a este

tópico.

Page 4: ASP.NET MVC

RROOTTEEAAMMEENNTTOO

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

27

num determinado recurso existente na aplicação (como veremos, o módulo4 de

roteamento encarrega-se de associar um URL a uma handler5, que, por sua vez, instancia

um controlador e executa um dos seus métodos, de forma a obter a vista que gerará o

HTML devolvido ao browser).

Para além dessa diferença, existe ainda outra: ao contrário do URL rewriting, o

roteamento usado em ASP.NET MVC permite a geração de URL compatíveis com

métodos expostos pelos controladores. Por outras palavras, podemos interagir com a

infraestrutura de roteamento e pedir-lhe para gerar um URL que “represente” um

determinado método de ação de um controlador.

Em ASP.NET MVC, precisamos de ter pelo menos uma rota ativa para

que um URL seja redirecionado para um método de ação de um controlador.

Uma rota é sempre caraterizada por um padrão, que é usado para verificar a sua

compatibilidade com o URL de um pedido HTTP. Este padrão pode, ou não,

conter parâmetros cujos valores serão apenas obtidos em runtime, depois de uma

rota ter sido considerada compatível com o URL de um pedido HTTP (na prática,

podemos pensar nos parâmetros como placeholders que serão substituídos pelos

valores indicados num URL compatível com o padrão). Quando o padrão contém

parâmetros, então a rota pode ainda indicar valores predefinidos e restrições

aplicáveis aos mesmos. Finalmente, importa ainda referir que uma rota dever ser

sempre identificada univocamente através de nome (definido durante o seu

registo na tabela de roteamento).

Processamento de várias rotas

Numa aplicação ASP.NET MVC, é normal definirmos várias rotas. Neste caso, a pesquisa

de uma rota termina quando a infraestrutura de roteamento encontra a primeira rota

compatível na tabela de rotas (coleção que contém todas as rotas previamente registadas).

Portanto, devemos ter algum cuidado na definição de rotas e garantir sempre que as rotas

mais específicas são efetivamente registadas na tabela de roteamento antes das rotas

generalistas.

4 Todos os pedidos HTTP tratados pela plataforma ASP.NET passam por várias fases. Estas fases

constituem a chamada pipeline ASP.NET. Os módulos são classes que podem intercetar uma destas fases para

modificar a informação do pedido atual. O leitor interessado pode obter mais detalhes sobre a construção destes

elementos em http://bit.ly/c96Wfw.

5 As handlers são classes responsáveis por devolver a resposta a um pedido HTTP. Em ASP.NET Web Forms,

todas as páginas ASPX são handlers. Em ASP.NET MVC, existe uma handler predefinida que trata todos os pedidos

efetuados através da interação com um método de ação de um controlador. O artigo existente em http://bit.ly/rY7ExF é

um bom ponto de partida para os interessados em obter mais informações sobre estes elementos.

Page 5: ASP.NET MVC

AASSPP..NNEETT MMVVCC

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

28

2.2.1 CCRRIIAAÇÇÃÃOO DDEE UUMMAA RROOTTAA

As rotas devem ser sempre criadas e registadas no início de uma

aplicação Web. É por isso que um projeto ASP.NET MVC gerado através do

template de Internet (ou de Intranet) invoca o método estático RegisterRoutes a

partir do método Application_Start definido no ficheiro global.asax.cs (por seu

lado, este é executado apenas uma vez, quando o primeiro recurso ASP.NET é

pedido). Por predefinição, o método RegisterRoutes contém código semelhante

ao seguinte:

public static void RegisterRoutes(RouteCollection routes){

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(

"Default", // nome da rota

"{controller}/{action}/{id}", //padrão URL com 3 parâmetros

new { controller = "Home", //valores predefinidos parâmetros

action = "Index",

id = UrlParameter.Optional }

);

}

A variável routes identifica a tabela de roteamento (representada

programaticamente por um objeto do tipo RouteCollection) que contém todas

as rotas, que, depois, são consumidas pelo módulo de roteamento. Concentremo-

-nos, para já, no método MapRoute. Na sua forma mais simples, este método

obriga-nos apenas a definir o nome da rota e o respetivo padrão. O excerto

seguinte ilustra o uso desta forma:

Routes.MapRoute( "teste",

"{parametro1}/{parametro2}/{parametro3}");

O padrão apresentado no excerto anterior define três parâmetros

(parametro1, parametro2 e parametro3). Na prática, um parâmetro é sempre

delimitado por { } e serve para identificar um segmento do URL cujo valor será

obtido em runtime. Não existem grandes restrições quanto aos nomes que podem

ser usados para identificar os parâmetros definidos num padrão. Na prática, con-

tudo, convém apenas utilizarmos nomes que possam ser usados como identi-

ficadores em C#, se quisermos que os seus valores alimentem automaticamente

Page 6: ASP.NET MVC

RROOTTEEAAMMEENNTTOO

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

29

eventuais parâmetros disponibilizados por um método de ação (a secção 2.2.2

apresenta mais pormenores sobre estas operações).

Ao intercetar um pedido, o módulo de roteamento é responsável por

verificar se o URL desse pedido é, ou não, compatível com alguma das rotas

previamente registadas na tabela de roteamento. Quando uma rota é considerada

compatível, então o módulo tem de obter os valores dos eventuais parâmetros do

padrão da rota a partir desse URL. A Tabela 2.1 procura ilustrar o processo de

obtenção de valores de parâmetros definidos num URL padrão.

URL VALORES DE PARÂMETROS

/filmes/cat/1 parametro1="filmes"

parametro2="cat"

parametro3="1"

/filmes/pt-PT/1 parametro1="filmes"

parametro2="pt-PT"

parametro3="1"

TTAABBEELLAA 22..11 –– Obtenção de valores de parâmetros a partir de um URL

Como a rota teste (apresentada no excerto de código anterior) define

três parâmetros, então é compatível com qualquer URL definido à custa de três

segmentos (um segmento é uma porção de texto delimitado por uma barra /).

Como é possível observar através do segundo exemplo apresentado na Tabela

2.1, o caráter / é o único que, efetivamente, delimita um segmento (repare-se

como pt-PT é atribuído ao segundo parâmetro, tendo o módulo simplesmente

ignorado o uso do caráter –).

Depois de obter os valores dos parâmetros a partir do URL do pedido

atual, o módulo de roteamento encarrega-se ainda de os guardar num dicionário

do tipo RouteValueDictionary (o nome de cada parâmetro é usado como chave

de cada entrada efetuada no dicionário). Como é óbvio, este dicionário pode ser

recuperado mais tarde através do contexto de roteamento representado por uma

instância do tipo RequestContext6 (voltaremos a este contexto mais tarde).

6 Como veremos, esta informação pode ser recuperada a partir de código usado num controlador ou

numa vista.

Page 7: ASP.NET MVC

AASSPP..NNEETT MMVVCC

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

30

2.2.2 PPAARRÂÂMMEETTRROOSS EESSPPEERRAADDOOSS PPEELLOO AASSPP..NNEETT MMVVCC

Como referimos, a plataforma ASP.NET MVC espera o uso de

parâmetros com determinados nomes. Todas as rotas reencaminhadas para

plataforma devem, pelo menos, definir dois parâmetros, designados por

controller e action. O valor de controller identifica o nome da classe

(controlador) que disponibiliza o método (de ação) identificado pelo valor do

segundo parâmetro (action). Por convenção, a plataforma encarrega-se de

adicionar o prefixo Controller ao valor do parâmetro e usa esse nome para

procurar um tipo que implementa a interface IController (note-se que a

capitulação não é tida em conta nesta pesquisa).

O parâmetro action e a interface IController

O parâmetro action é apenas usado para identificar o método de ação quando o

controlador em causa reutiliza a classe base Controller. Controladores que

implementem diretamente a interface IController são responsáveis por definir as suas

próprias convenções e mapeamentos entre rotas e controladores.

Como na maior parte das vezes a criação de um novo controlador implica a extensão da

classe Controller, então é normal dizermos que temos de garantir sempre a existência

de um parâmetro de roteamento designado por action.

Portanto, a rota que usámos na secção 2.1 acaba por não ser uma rota

MVC válida. Para a usarmos numa aplicação ASP.NET MVC, temos de alterá-la

por forma a garantir que um pedido inicializa sempre os parâmetros controller

e action. O excerto seguinte ilustra uma forma de a tornamos numa rota que

pode ser interpretada pela plataforma ASP.NET MVC:

Routes.MapRoute( "teste",

"{controller}/{action}/{parametro3}");

Se reutilizamos o primeiro URL apresentado na Tabela 2.1, então é

possível afirmarmos que o URL /filmes/cat/1 será tratada pelo método Cat

exposto pela classe FilmesController. Apesar de o segundo URL apresentado

pela tabela ser compatível com o padrão da regra anterior, a verdade é que a rota

obtida por ele não conduzirá à execução de um método de ação, uma vez que não

é possível termos um método designado por pt-PT em C# (no Capítulo 3,

veremos como é que podemos associar um nome C# inválido a um método de

ação). Ou seja, neste segundo exemplo, o problema não reside na obtenção de

uma rota compatível, mas sim no facto de o valor do parâmetro action não

corresponder a um nome válido em C#.

Page 8: ASP.NET MVC

RROOTTEEAAMMEENNTTOO

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

31

2.2.3 MMAAPPEEAAMMEENNTTOO DDEE PPAARRÂÂMMEETTRROOSS DDEE RROOTTEEAAMMEENNTTOO EEMM

PPAARRÂÂMMEETTRROOSS DDOO MMÉÉTTOODDOO DDEE AAÇÇÃÃOO

A plataforma ASP.NET MVC consegue ainda transformar os restantes

parâmetros de roteamento indicados por um padrão da rota em parâmetros do

método de ação que será invocado. Para que isto aconteça, os nomes dos

parâmetros do método de ação têm de ser os mesmos que os especificados pelo

padrão da rota e a plataforma tem de conseguir converter as strings obtidas a

partir do URL atual nos tipos dos parâmetros usados nos métodos de ação. Por

exemplo, suponhamos que o método Cat é definido da seguinte forma:

public class FilmesController:Controller {

public ActionResult Cat(Int32 parametro3) {

//obtem filmes da categoria

return View();

}

}

Ao encontrar a informação processada pelo módulo de roteamento a

partir do URL /filmes/cat/1, a plataforma ASP.NET MVC acaba por atribuir o

valor 1 ao parâmetro parametro3 durante a invocação do método Cat. Isto só é

possível porque ambos os parâmetros (o de roteamento e o definido pelo método

de ação) possuem o mesmo nome e porque a plataforma consegue converter o

valor extraído do URL (uma string) no tipo esperado pelo parâmetro do método

de ação (voltaremos a esta conversão noutra secção).

Antes de avançarmos, importa ainda referir que todo o trabalho de

mapeamento de parâmetros de roteamento em parâmetros de métodos é feito

pela plataforma ASP.NET MVC a partir do dicionário de valores preenchido pela

infraestrutura de roteamento. Ou seja, apesar de estarmos a falar acerca destes

mapeamentos neste capítulo, a verdade é que o trabalho desempenhado pela

infraestrutura de roteamento limita-se apenas a preencher o dicionário de dados

com informação obtida a partir do URL do pedido HTTP. Este dicionário é

depois usado por um componente especial, designado por model binder, para

inicializar os parâmetros passados ao método de ação responsável pelo

tratamento do pedido HTTP atual (voltaremos a este tópico no Capítulo 3).

Page 9: ASP.NET MVC

AASSPP..NNEETT MMVVCC

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

32

2.2.4 UUSSOO DDEE VVAALLOORREESS LLIITTEERRAAIISS

Apesar de todos os exemplos apresentados até agora terem usado

parâmetros nos segmentos, a verdade é que o padrão de uma rota também pode

conter valores literais7. O excerto seguinte ilustra este cenário:

/historico/{controller}/{action}/{parametro3}

Para que um URL seja compatível com a regra anterior, tem de começar

sempre pela string /historico/. Por exemplo, o URL /historico/Filmes

/Cat/1 é compatível com este padrão, mas o URL /Filmes/Cat/1 já não é.

Importa ainda referir que um segmento pode ter um ou mais parâmetros,

que podem, ou não, ser misturados com valores literais. A única restrição

prende-se com o facto de dois parâmetros não poderem ser definidos

consecutivamente. O excerto seguinte ilustra estes cenários:

/historico/{lingua}-{pais}/{controller}/{action} //válido

{controller}/{action}.{outroValor} //válido: . separa parâmetros

{controller}{action}/{id} //inválido: dois parâmetros seguidos

2.2.5 PPAARRÂÂMMEETTRROO CCAATTCCHH AALLLL

A infraestrutura de roteamento permite ainda o mapeamento de vários

segmentos de um URL num único parâmetro de roteamento, através do uso de

um parâmetro catch all. O parâmetro catch all é um parâmetro especial, cujo nome

é prefixado obrigatoriamente pelo caráter *. O padrão de uma rota só pode ter

um parâmetro deste tipo e este parâmetro, quando definido, deve ocupar sempre

o seu último segmento. O exemplo seguinte ilustra o uso deste tipo de

parâmetros no padrão de uma rota:

Routes.MapRoute( "teste",

"{controller}/{action}/{*extra}");

O excerto seguinte apresenta vários URL e explica a forma como os

parâmetros são inicializados a partir do parsing do URL (supondo que a regra

apresentada no excerto anterior é a única presente na tabela de roteamento):

URL: /Filmes/Cat/Opcao/Outra

7 Em computação, a expressão “valor literal” é usada para representar um valor constante no código

de uma aplicação. Por exemplo, a instrução int a = 10; inicializa a variável a com o valor literal 10.

Page 10: ASP.NET MVC

RROOTTEEAAMMEENNTTOO

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

33

//controller = "Filmes"

//action = "Cat"

//extra = "Opcao/Outra"

URL: /Filmes/Cat

//controller = "Filmes"

//action = "Cat"

//extra = ""

Note-se como o segundo URL apresentado no exemplo é compatível com

a regra de roteamento "{controller}/{action}/{*extra}", sendo o

parâmetro extra inicializado com uma string vazia.

2.2.6 VVAALLOORREESS PPRREEDDEEFFIINNIIDDOOSS

O algoritmo de mapeamento de um URL numa rota depende ainda da

atribuição de valores predefinidos aos parâmetros. Para ilustrar este ponto,

vamos começar por alterar a rota que temos usado até aqui:

Routes.MapRoute( "teste",

"{controller}/{action}/{parametro3}",

new {parametro3 = UrlParameter.Optional});

A atribuição de um valor predefinido ao parâmetro parametro3 aumenta

o âmbito de compatibilidade dos URL. Como vimos nas secções anteriores, a

inexistência de um valor predefinido fazia com que um URL só fosse compatível

se definisse explicitamente o valor de todos os parâmetros definidos pelo padrão.

A partir da altura em que atribuímos um valor predefinido a um parâmetro, a

definição desse parâmetro num URL deixa de ser obrigatória para que ele seja

considerado compatível com um padrão de uma rota. Portanto, a partir de agora,

todos os URL apresentados no excerto seguinte são compatíveis com a nossa

regra teste:

/Filmes/Cat/1 //parametro3 = 1

/Filmes/Cat //parametro3 não definido no dicionário

A atribuição do valor UrlParameter.Optional pode causar alguma

estranheza à primeira vista. Porque não atribuir uma string vazia ("")? Apesar de

o resultado final ser muito semelhante, existe uma diferença importante entre

ambas as opções: o uso do valor UrlParameter.Optional faz com que o

Page 11: ASP.NET MVC

AASSPP..NNEETT MMVVCC

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

34

dicionário preenchido pelo módulo de roteamento não contenha uma entrada

para o parâmetro parametro3. Se tivéssemos optado pela string vazia, o

dicionário acabaria por ter uma entrada para o parâmetro inicializada com a

string (vazia).

Como é óbvio, não estamos limitados a definir apenas um valor por

predefinição. No excerto seguinte, modificamos a nossa rota, por forma a

garantir que todos os parâmetros usados possuem valores predefinidos:

Routes.MapRoute( "teste",

"{controller}/{action}/{parametro3}",

new {

controller = "Filme",

action = "Cat",

parametro3 = UrlParameter.Optional});

A partir desta altura, qualquer um dos URL apresentados no excerto

seguinte é compatível com a nossa rota teste:

URL: /Filme/Cat/1

//controller="Filme"

//action="Cat"

//parametro3=1

/Filme

//controller="Filme"

//action="Cat"

//parametro3 inexistente no dicionário

/

//controller="Filme"

//action="Cat"

//parametro3 inexistente no dicionário

Qualquer um dos URL apresentados na lista anterior acaba por ser

“redirecionado” para o método Cat exposto pela classe FilmeController. Nesta

altura, importa salientar que a atribuição de um valor predefinido a um

parâmetro obriga-nos a atribuir valores predefinidos a todos os parâmetros

seguintes definidos no padrão. Por exemplo, e recuperando a nossa rota teste

(que usa o padrão {controller}/{action}/{parametro3}), se atribuímos um

Page 12: ASP.NET MVC

RROOTTEEAAMMEENNTTOO

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

35

valor predefinido ao parâmetro action, então temos também de atribuir um ao

parâmetro parametro3. A rota seguinte não respeita esta regra, já que atribui

apenas um valor predefinido ao parâmetro action:

Routes.MapRoute( "teste",

"{controller}/{action}/{parametro3}",

new {

action = "Cat"

});

Se não respeitarmos esta regra, a plataforma acaba por ignorar os valores

predefinidos quando testa a compatibilidade de um URL.

Tenho mesmo de definir os parâmetros controller e action no URL?

A atribuição de valores predefinidos aos parâmetros faz com que isso deixe de ser

obrigatório. O excerto seguinte ilustra esta estratégia:

Routes.MapRoute( "outroTeste",

"historico/{action}/{id}",

new {controller = "Filmes",

action = "Cat",

id = UrlParameter.Optional } );

Apesar de o padrão do URL não usar o parâmetro controller, a verdade é que o

dicionário de parâmetros gerado pelo módulo de roteamento contém entradas

identificadas pelos nomes controller e action. A partir desta altura, a plataforma

ASP.NET MVC tem toda a informação necessária para reencaminhar o pedido atual para

o controlador adequado.

2.2.7 AAPPLLIICCAAÇÇÃÃOO DDEE RREESSTTRRIIÇÇÕÕEESS

Se quisermos, podemos ainda definir restrições extra numa rota, que

influenciam a sua compatibilidade com o URL de um pedido. Por exemplo,

suponhamos que registamos uma rota semelhante à seguinte:

Routes.MapRoute( "teste",

"{controller}/{action}/{parametro3}",

new {

controller = "Filme",

Page 13: ASP.NET MVC

AASSPP..NNEETT MMVVCC

©© FFCCAA –– EEddiittoorraa ddee IInnffoorrmmááttiiccaa

36

action = "Cat",

parametro3 = UrlParameter.Optional

});

A informação definida no registo da rota anterior não é suficiente para,

por exemplo, especificar que o parâmetro parametro3 só pode receber um

número inteiro. Esse requisito pode ser explicitado através do uso de uma

expressão regular8 aplicada a esse parâmetro, conforme ilustrado através do

excerto seguinte:

Routes.MapRoute( "teste",

"{controller}/{action}/{parametro3}",

new {

controller = "Filme",

action = "Cat",

parametro3 = UrlParameter.Optional

},

new{parametro3 = @"\d+"}

);

O overload do método MapRoute apresentado no excerto anterior recorre a

uma expressão regular para garantir que a rota é considerada compatível apenas

com URL onde o parâmetro de roteamento parametro3 é definido à custa de um

número inteiro (note-se ainda como a restrição é associada ao parâmetro através

da introdução de um novo objeto anónimo, onde cada propriedade identifica o

nome do parâmetro de roteamento ao qual a restrição indicada deve ser

aplicada).

O leitor com experiência em expressões regulares não deixará de observar

que a regra \d+ não é compatível só com valores numéricos, já que, por exemplo,

aceita strings do tipo asd123aa (obviamente, não era isso que pretendíamos

quando aplicámos a regra). A solução para este problema seria simples e passaria

pela adição dos carateres de início e final de linha à expressão anterior. Contudo,

isso não é necessário, uma vez que a infraestrutura de roteamento encarrega-se

8 As expressões regulares podem ser vistas como uma minilinguagem que permite efetuar operações

de pesquisa e substituição sobre texto. O leitor interessado pode obter mais detalhes sobre estas expressões em

http://bit.ly/bPCm7j.