3. Controladores, Ações, Roteamento
Vamos considerar a arquitetura de uma aplicação ASP.NET MVC:
![]() |
Neste capítulo, examinamos o processo que encaminha o pedido [1] para o controlador e a ação [2a] que o irá processar, um mecanismo conhecido como encaminhamento. Apresentamos também as várias respostas [3] que uma ação pode devolver ao navegador. Estas podem ser algo diferente de uma vista V [4b].
3.1. A estrutura de um projeto ASP.NET MVC
Vamos criar o nosso primeiro projeto ASP.NET MVC utilizando o Visual Studio Express 2012. Iremos adicioná-lo [1] à solução utilizada no capítulo anterior:
![]() |
![]() |
- em [2], o nome do novo projeto;
- em [3, 4], escolhemos um projeto ASP.NET MVC básico. Este modelo fornece-nos uma aplicação web vazia que, no entanto, inclui todos os recursos (DLLs, bibliotecas JavaScript, etc.) necessários para começar.
O projeto resultante é apresentado em [5]. Vamos torná-lo [6] o projeto inicial da solução:
![]() |
Observe os seguintes pontos em [5]:
- a arquitetura do projeto reflete o seu modelo MVC:
- os controladores C serão colocados na pasta [Controllers],
- os modelos de dados M serão colocados na pasta [Models],
- as vistas V serão colocadas na pasta [Views],
![]() |
- em [1], o ficheiro [Site.css] será o ficheiro CSS predefinido da aplicação;
- em [2], estão disponíveis várias bibliotecas JavaScript;
- em [3], existem três vistas específicas: _ViewStart, _Layout e Error.
O ficheiro [_ViewStart] é o seguinte:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
- Linha 1: O caractere @ marca o início de um bloco C# dentro da vista. De facto, é possível incluir código C# numa vista;
- linha 2: define uma variável Layout que especifica a vista pai para todas as vistas. Corresponde à página mestre na estrutura clássica do ASP.NET.
O ficheiro [ _Layout ] é o seguinte:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
@RenderBody()
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
Quando uma vista da pasta [Views] é renderizada, o seu corpo será renderizado pela linha 11 acima. Isto significa que a vista não precisa de incluir as tags <html>, <head> e <body>. Estas são fornecidas pelo ficheiro acima. Por enquanto, este ficheiro é bastante enigmático. Vamos simplificá-lo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Tutoriel ASP.NET MVC</title>
</head>
<body>
<h2>Tutoriel ASP.NET MVC</h2>
@RenderBody()
</body>
</html>
- linha 6: o título comum a todas as visualizações;
- linha 9: o cabeçalho comum a todas as visualizações;
- linha 10: o conteúdo específico da vista apresentada.

- [Web.config] é o ficheiro de configuração da aplicação web. É complexo. Terá de o modificar ao utilizar o framework [Spring.net] numa arquitetura multicamadas.
- [Global.asax] contém o código executado quando a aplicação é iniciada. Geralmente, este código utiliza os vários ficheiros de configuração da aplicação, incluindo [Web.config].
3.2. Roteamento de URL padrão
O código em [Global.asax] é atualmente o seguinte:
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace Exemple_01
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
...
}
}
}
- Linha 6: o namespace da classe. É derivado diretamente do nome do projeto e está listado nas propriedades do projeto:

![]() |
Definimos [1] como o namespace padrão. Este é então utilizado por predefinição para todas as classes que serão criadas no projeto.
Voltemos ao código em [Global.asax]:
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace Exemple_01
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
...
}
}
}
- linha 9: a classe [MvcApplication] deriva da classe [HttpApplication]. O nome [MvcApplication] pode ser alterado;
- linha 11: O método [Application_Start] é o método executado quando a aplicação web é iniciada. É executado apenas uma vez. É aqui que a aplicação é inicializada.
O código para [Application_Start] é atualmente o seguinte:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Por enquanto, não é necessário compreender todo este código. As linhas 5–8 definem as rotas aceites pela aplicação web. Voltemos à arquitetura de uma aplicação ASP.NET MVC:
![]() |
Explicámos que o [Front Controller] deve encaminhar um URL para a ação responsável por o processar. Uma rota é utilizada para associar um padrão de URL a uma ação. Estas rotas são definidas na pasta [App_Start] do projeto pelas classes [WebApiConfig, FilterConfig, RouteConfig, BundleConfig]:

Por enquanto, estamos interessados apenas na classe [RouteConfig]:
using System.Web.Mvc;
using System.Web.Routing;
namespace Exemple_01
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
As linhas 12–16 definem o formato dos URLs aceites pela aplicação. Isto é chamado de rota. Podem existir várias rotas possíveis (= vários padrões de URL possíveis). Estas distinguem-se umas das outras pelo seu nome (linha 13). O formato dos URLs da rota é definido na linha 14. Aqui, o URL terá três componentes:
- {controller}: o nome de uma classe derivada de [Controller]. Será procurada na pasta [Controllers] do projeto. Por convenção, se a URL for /X/Y/Z, o controlador responsável por tratar esta URL será a classe XController. O sufixo Controller é adicionado ao nome do controlador presente na URL;
- {action}: o nome de um método no controlador especificado acima. Este método receberá os parâmetros que acompanham a URL e processá-los-á. Este método pode devolver vários resultados:
- void: a ação irá construir a resposta para o navegador do cliente
- String: a ação devolve uma cadeia de caracteres ao cliente;
- ViewResult: devolve uma vista ao cliente;
- PartialViewResult: devolve uma vista parcial;
- EmptyResult: é enviada uma resposta vazia ao cliente;
- RedirectResult: instrui o cliente a redirecionar para um URL
- RedirectToRouteResult: igual ao anterior, mas a URL é construída a partir das rotas da aplicação;
- JsonResult: envia uma resposta JSON
- JavaScriptResult: devolve código JavaScript ao cliente;
- ContentResult: devolve um fluxo HTML ao cliente sem passar por uma vista;
- FileContentResult: devolve um ficheiro ao cliente;
- FileStreamResult: igual ao anterior, mas através de um método diferente;
- FilePathResult: ...
- {id}: um parâmetro que será passado para a ação. Para que isto funcione, a ação deve ter um parâmetro chamado id.
A linha 15 define valores padrão quando a URL não tem o formato esperado /{controller}/{action}/{id}. Também indica que o parâmetro {id} na URL é opcional. Aqui está uma lista de URLs incompletas e a URL completada com os valores padrão:
URL original | URL completada |
/ | /Home/Index |
/Fazer | /Fazer/Índice |
/Fazer/Algo | /Fazer/Algo |
/Fazer/Algo/4 | /Fazer/Algo/4 |
/Fazer/Algo/x/y/z | URL não encaminhada |
3.3. Criar um controlador e uma primeira ação
Vamos criar um primeiro controlador:

![]() |
- Em [1], introduza o nome do controlador com o sufixo [Controller];
- em [2], crie um controlador MVC vazio;
- em [3], já foi criado.
O código para [FirstController] é o seguinte:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Exemple_01.Controllers
{
public class FirstController : Controller
{
//
// GET: /First/
public ActionResult Index()
{
return View();
}
}
}
- linha 7: foi gerado um namespace padrão;
- linha 9: a classe [FirstController] deriva da classe [System.Web.Mvc.Controller];
- linhas 14–17: foi gerada uma ação [Index] por predefinição. É pública. Isto é importante; caso contrário, não será encontrada. Retorna um tipo [ActionResult], que é uma classe abstrata da qual derivam a maioria dos resultados normalmente devolvidos por uma ação. Este é um tipo «catch-all» que pode ser especificado substituindo-o pelo nome real do tipo devolvido;
- Linha 16: O método não faz nada. Simplesmente devolve uma vista, ou seja, um tipo [ViewResult]. O nome da vista não é especificado. Neste caso, o framework procura na pasta [Views/First] uma vista com o mesmo nome da ação, que aqui é [Index.cshtml].
Vamos criar a vista [Index.cshtml]:
![]() |
- em [1], clique com o botão direito do rato no código da ação e selecione a opção [Adicionar Vista];
- em [2], o assistente sugere uma vista com o mesmo nome da ação. É isso que queremos aqui;
- em [3], por predefinição, é sugerida a utilização da página mestre [_Layout.cshtml];
- em [4], uma vez confirmado, o assistente cria a vista numa subpasta da pasta [Views] com o nome do controlador (First).
O código gerado para a vista [Index] é o seguinte:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
- Linhas 1–3: código C# que define uma variável;
- linha 5: uma tag HTML.
Substitua todo o código anterior por este:
<strong>Vue [Index]...</strong>
Resumindo:
- temos um controlador C# chamado [First];
- temos uma ação chamada [Index] que solicita a exibição de uma vista chamada [Index];
- temos a vista V [Index].
Podemos chamar a ação [Index] de duas maneiras:
- /First/Index;
- /Primeiro, uma vez que [Index] é também a ação padrão nas rotas.
Vamos executar a aplicação (CTRL-F5). Obtemos a seguinte página:

Em [1], o URL solicitado era http://localhost:49302. Não existe nenhum caminho. Sabemos que o nosso router espera URLs na forma /{controller}/{action}/{id}. Uma vez que estes elementos estão em falta, são utilizados os valores por predefinição. O URL passa a ser http://localhost:49302/Home/Index. O controlador [Home] não existe. Por conseguinte, o URL é rejeitado.
Agora vamos tentar a URL http://localhost:49302/First/Index, digitando-a diretamente no navegador:
![]() |
A página acima foi gerada pela ação [Index] do controlador [First]. A página gerada por esta ação é a vista [Index], cujo código era o seguinte:
<strong>Vue [Index]...</strong>
Gera a parte [1]. A parte [2], por outro lado, provém da página mestre [_Layout] que definimos anteriormente:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Tutoriel ASP.NET MVC</title>
</head>
<body>
<h2>Tutoriel ASP.NET MVC</h2>
@RenderBody()
</body>
</html>
A linha 9 gerou a secção [2] da página. A vista [Index], no entanto, só aparece na linha 10.
Se visualizarmos o código-fonte da página recebida, podemos ver que a página [Índice] está de facto incluída (linha 10 abaixo) na página [Layout]:
Agora vamos experimentar a URL [/First]:

A URL [/First] estava incompleta. Foi completada com os valores predefinidos da rota e passou a ser [/First/Index]. Obtemos, portanto, o mesmo resultado que anteriormente.
3.4. Ação com um resultado do tipo [ContentResult] - 1
Vamos criar uma nova ação no controlador [First]:
using System.Text;
using System.Web.Mvc;
namespace Exemple_01.Controllers
{
public class FirstController : Controller
{
// Index
public ViewResult Index()
{
return View();
}
// Action01
public ContentResult Action01()
{
return Content("<h1>Action [Action01]</h1>", "text/plain", Encoding.UTF8);
}
}
}
A nova ação é definida nas linhas 14–18. Ela simplesmente devolve uma cadeia de caracteres utilizando o método [Content] (linha 16) da classe [Controller] (linha 6). Os parâmetros do método são:
- a string de resposta;
- um indicador do tipo de texto que está a ser enviado: «text/plain», «text/html», «text/xml», etc. Este indicador é chamado de tipo MIME (http://fr.wikipedia.org/wiki/Type_MIME);
- o terceiro parâmetro especifica o tipo de codificação utilizado para o texto.
Em vez de utilizar o tipo abstrato [ActionResult], os nossos métodos especificam o tipo de retorno real (linhas 9 e 14).
Vamos solicitar a URL [/First/Action01]. Obtemos a seguinte página:

Vamos ver o código-fonte da página recebida:
O navegador recebeu apenas o texto enviado pela ação e nada mais. Este modo é útil quando se pretende solicitar dados brutos do servidor web sem a marcação HTML circundante. Repare que o navegador não interpretou a tag HTML <h1>. Para compreender porquê, vamos analisar as trocas HTTP no Chrome:
O navegador enviou os seguintes cabeçalhos HTTP:
O servidor respondeu com os seguintes cabeçalhos:
- Linha 3: define o tipo de documento. Vemos os atributos definidos no método [Action01]. Foi porque o navegador foi informado de que o documento era do tipo "text/plain" e não "text/html" que não interpretou a tag <h1> que estava no documento recebido.
3.5. Ação com um resultado do tipo [ContentResult] - 2
Vamos considerar a seguinte terceira ação:
using System.Text;
using System.Web.Mvc;
namespace Exemple_01.Controllers
{
public class FirstController : Controller
{
...
// Action02
public ContentResult Action02()
{
string data = "<action><name>Action02</name><description>renvoie un texte XML</description></action>";
return Content(data, "text/xml", Encoding.UTF8);
}
}
}
- linha 12: definimos um texto XML;
- linha 13: enviamos-o para o navegador, especificando que se trata de XML com o tipo MIME «text/xml».
No navegador, obtemos a seguinte página:

Vejamos a resposta HTTP do servidor no Chrome:
- Linha 3: especifica o tipo de documento. Os atributos definidos no método [Action02] estão incluídos aqui;
- Linha 12: O tamanho em bytes do documento enviado pelo servidor.
O documento enviado pelo servidor é este (captura de ecrã do Chrome):

3.6. Ação com um resultado do tipo [JsonResult]
Vamos adicionar a seguinte ação ao controlador [First]:
// Action03
public JsonResult Action03()
{
dynamic personne = new ExpandoObject();
personne.nom = "someone";
personne.age = 20;
return Json(personne,JsonRequestBehavior.AllowGet);
}
- linha 4: uma variável do tipo dynamic. Em tempo de execução, é possível adicionar livremente propriedades a essa variável. A propriedade é criada ao mesmo tempo que é inicializada;
- linhas 5-6: inicializamos duas propriedades, nome e idade;
- linha 7: devolve a representação JSON (JavaScript Object Notation) do objeto. O JSON permite que um objeto seja serializado numa cadeia de caracteres e, inversamente, que uma cadeia de caracteres seja deserializada num objeto. É uma alternativa à serialização/deserialização XML;
- linha 2: a ação retorna um tipo [JsonResult]. Este tipo só pode ser retornado para uma solicitação POST. Se pretender retorná-lo para um método GET, deve definir o segundo parâmetro do construtor da classe Json (linha 7) como JsonRequestBehavior.AllowGet.
Quando solicita a URL [/First/Action03], o navegador apresenta o seguinte:

A resposta HTTP do servidor é a seguinte:
- Linha 3: especifica que o documento enviado é JSON;
- linha 10: o documento enviado tem 58 bytes. É o seguinte:
O elemento dinâmico [person] é visto pelo JSON como uma matriz de dicionários, em que cada dicionário:
- corresponde a um campo da variável [person];
- tem duas chaves, "Key" e "Value". "Key" tem o nome do campo como seu valor associado e "Value" tem o valor do campo.
3.7. Ação com um resultado [string]
Vamos adicionar a seguinte ação ao controlador [First]:
// Action04
public string Action04()
{
return "<h3>Contrôleur=First, Action=Action04</h3>";
}
Quando solicitamos a URL [/First/Action04] no Chrome, obtemos a seguinte resposta:

Podemos ver que a tag <h3> foi interpretada. Vejamos a resposta HTTP do servidor:
e o seguinte documento:
Como se pode ver na linha 3, o servidor indicou que estava a enviar texto em formato HTML. É por isso que o navegador interpretou a tag <h3>. Quando se pretende enviar texto simples, é, portanto, preferível devolver um [ContentResult] em vez de uma [string]. O [ContentResult] permite-nos especificar um tipo MIME de "text/plain" para indicar que estamos a enviar texto sem formatação, que o navegador não tentará interpretar.
3.8. Ação com um tipo [EmptyResult]
Considere a seguinte nova ação:
// Action05
public EmptyResult Action05()
{
return new EmptyResult();
}
A ação simplesmente devolve um tipo [EmptyResult]. Neste caso, o servidor envia uma resposta vazia ao cliente, conforme mostrado na sua resposta HTTP:
- Linha 9: O servidor informa ao seu cliente que está a enviar um documento vazio.
3.9. Ação com um resultado do tipo [RedirectResult] - 1
Considere a seguinte nova ação:
// Action06
public RedirectResult Action06()
{
return new RedirectResult("/First/Action05");
}
A ação retorna um tipo [RedirectResult]. Este tipo permite enviar um pedido de redirecionamento ao cliente para o URL especificado no construtor (linha 4). O cliente enviará então um novo pedido GET para [/First/Action05]. O cliente faz, portanto, dois pedidos no total.
O navegador exibe o resultado da segunda solicitação:

Vamos examinar a resposta HTTP do servidor no Chrome:

Acima, vemos as duas solicitações do navegador. Vamos examinar a primeira solicitação [Action06]. A resposta HTTP do servidor é a seguinte:
- Linha 1: O servidor respondeu com um código de estado 302 Found. Anteriormente, era 200 OK, o que significa que o documento solicitado foi encontrado. O código 302 indica que foi solicitado um redirecionamento. O URL de redirecionamento é fornecido na linha 4. Este corresponde ao URL de redirecionamento que especificámos no código de ação;
- Linha 11: O servidor indica que, com a sua resposta HTTP, está a enviar um documento text/html (linha 3) de 132 bytes (linha 11). Quando examinamos a resposta ao pedido [Action06] no Chrome, esta está vazia, como esperado. Provavelmente há uma explicação, mas não sei qual é.
Devido ao redirecionamento, o navegador faz uma nova solicitação GET para a URL especificada na linha 4 acima, como pode ser visto no Chrome na linha 1 abaixo:
3.10. Ação com um resultado do tipo [RedirectResult] - 2
Considere a seguinte nova ação:
// Action07
public RedirectResult Action07()
{
return new RedirectResult("/First/Action05",true);
}
Na linha 4, adicionámos um segundo parâmetro ao construtor [RedirectResult]. Trata-se de um valor booleano cujo valor padrão é false. Quando definido como true, modifica a resposta HTTP enviada ao cliente. Passa a ser:
Assim, o código de resposta enviado ao cliente é agora 301 Movido Permanentemente. O redirecionamento ocorre como antes, mas indicamos que este redirecionamento é permanente. Isto permite que os motores de busca substituam o URL antigo pelo novo nos seus resultados.
3.11. Ação com um resultado do tipo [RedirectToRouteResult]
Considere a seguinte nova ação:
// Action08
public RedirectToRouteResult Action08()
{
return new RedirectToRouteResult("Default",new RouteValueDictionary(new {controller="First",action="Action05"}));
}
- Linha 2: A ação retorna um tipo [RedirectToRouteResult]. Este tipo permite redirecionar um cliente para um URL especificado, não através de uma string como antes, mas através de uma rota.
As rotas são definidas em [App_Start/RouteConfig]. Atualmente, existe apenas uma:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
- Na linha 4, o cliente recebe a instrução para redirecionar para a rota denominada [Default], com a variável controller definida como "First" e a variável action definida como "Action05". O sistema de roteamento irá então gerar a URL de redirecionamento /First/Action05. Isto é mostrado na resposta HTTP do servidor:
- linha 1: o redirecionamento;
- linha 4: o URL de redirecionamento gerado pelo sistema de encaminhamento de URLs.
3.12. Ação com um tipo de retorno [void]
Considere a seguinte nova ação:
// Action09
public void Action09()
{
string nom = Request.QueryString["nom"] ?? "inconnu";
Response.AddHeader("Content-Type", "text/plain");
Response.Write(string.Format("<h3>Action09</h3>nom={0}", nom));
}
- linha 2: a ação não devolve nenhum resultado. Escreve diretamente no fluxo de resposta enviado ao cliente;
- linha 4: recuperamos um parâmetro potencial chamado [name] da solicitação. Este está acessível através da propriedade [Request] da classe [Controller], da qual o controlador [First] herda. O parâmetro [name] passado no formato [/First/Action09?name=something] está disponível em Request.QueryString["name"]. A sintaxe da linha 4 é equivalente a:
- linha 5: a resposta enviada ao cliente é acessível através da propriedade [Response] da classe [Controller], da qual o controlador [First] herda;
- linha 5: definimos o cabeçalho HTTP [Content-Type], que indica a natureza do documento que o servidor está prestes a enviar ao cliente. Aqui, «text/plain» indica que o documento é texto simples que não deve ser interpretado pelo navegador;
- linha 6: inserimos uma sequência de caracteres no corpo da resposta. Incluímos tags HTML que não devem ser interpretadas pelo navegador, uma vez que este já terá recebido anteriormente o cabeçalho HTTP [Content-Type: text/plain]. É isso que queremos verificar.
Vamos compilar o projeto e solicitar a URL [/First/Action09?name=someone ][1] e, em seguida, a URL [/First/Action09 ] [2]:
![]() |
Agora, vamos ver a resposta HTTP do servidor no Chrome:
- linha 3: vemos o cabeçalho HTTP que definimos no código da ação.
3.13. Um segundo controlador
Vamos criar um segundo controlador no projeto. Seguiremos o método descrito na secção 3.1, na página 36. Vamos chamá-lo de [Second].

O código gerado é o seguinte:
namespace Exemple_01.Controllers
{
public class SecondController : Controller
{
//
// GET: /Second/
public ActionResult Index()
{
return View();
}
}
}
Vamos modificá-lo da seguinte forma:
using System.Text;
using System.Web.Mvc;
namespace Exemple_01.Controllers
{
public class SecondController : Controller
{
// /Second/Action01
public ContentResult Action01()
{
return Content("Contrôleur=Second, Action=Action01", "text/plain", Encoding.UTF8);
}
}
}
Então, vamos solicitar a URL [/Second/Action01] utilizando um navegador. Obtemos a seguinte resposta:

Esta URL foi solicitada através de uma solicitação HTTP GET, conforme mostrado nos registos HTTP da solicitação no Chrome:
A URL também pode ser solicitada através de uma solicitação HTTP POST. Para demonstrar isso, vamos usar novamente a aplicação [Advanced Rest Client]:
![]() |
- Em [1], inicie a aplicação (no separador [Aplicações] de um novo separador do Chrome);
- em [2], selecione a opção [Solicitar];
- em [3], especifique a URL solicitada;
- em [4], especifique que o URL deve ser solicitado utilizando um pedido POST;
Ativamos os registos do Chrome (CTRL-I) para visualizar a resposta HTTP do servidor. Quando clicamos em [Enviar] para executar o pedido anterior, as trocas HTTP são as seguintes:
O navegador envia a seguinte solicitação:
- linha 1: o URL é, de facto, solicitado com um POST;
- Linha 4: O tamanho em bytes dos elementos enviados. Não há nenhum aqui.
A resposta HTTP do servidor é a seguinte:
- linha 3: o servidor envia um documento de texto não formatado (simples);
- linha 12: 148 caracteres.
O documento enviado é o seguinte:

Recebemos o mesmo documento que com o pedido GET.
3.14. Ação filtrada por um atributo
Vamos criar a seguinte nova ação:
// /Second/Action02
[HttpPost]
public ContentResult Action02()
{
return Content("Contrôleur=Second, Action=Action02", "text/plain", Encoding.UTF8);
}
A ação [Action02] é semelhante à ação [Action01], mas especifica que só é acessível através de um pedido HTTP POST (linha 2). Podem ser utilizados outros atributos:
HttpGet | atende apenas à solicitação GET |
HttpHead | atende apenas à solicitação HEAD |
HttpOptions | suporta apenas o comando OPTIONS |
HttpPut | suporta apenas o comando PUT |
HttpDelete | é utilizado apenas para o comando DELETE |
Vamos solicitar a URL [/Second/Action02] diretamente no navegador. A solicitação é então feita através de um GET. O navegador exibe então a seguinte resposta:

A resposta HTTP do servidor foi a seguinte:
- Linha 1: O código HTTP 404 Não encontrado indica que o servidor não conseguiu encontrar o documento solicitado. Aqui, a ação [Action02] não conseguiu processar o pedido GET porque apenas processa pedidos POST;
- Linha 3: O tamanho do documento devolvido. Esta é a página que foi apresentada pelo navegador:

3.15. Recuperar elementos de uma rota
Nas duas ações descritas acima, escrevemos algo como:
public ContentResult Action02()
{
return Content("Contrôleur=Second, Action=Action02", "text/plain", Encoding.UTF8);
}
Os nomes do controlador e da ação foram codificados de forma rígida no código. Se alterarmos estes nomes, o código deixa de estar correto. Podemos aceder ao controlador e à ação da seguinte forma:
// /Second/Action03
public ContentResult Action03()
{
string texte = string.Format("Contrôleur={0}, Action={1}", RouteData.Values["controller"], RouteData.Values["action"]);
return Content(texte, "text/plain", Encoding.UTF8);
}
A rota definida em [App_Start/RouteConfig] é a seguinte:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Linha 3: Os três elementos da rota podem ser recuperados utilizando RouteData.Values["element"], onde element é um dos seguintes: [controller, action, id].
Vamos solicitar a URL [http://localhost:49302/Second/Action03]:

Recuperámos com sucesso tanto o nome do controlador como o nome da ação.











