ASP.NET MVC – Design de controllers – Parte 1

Numa aplicação Asp.net MVC ,controllers existem para responder qualquer requisição que um usuario faça através da interface de usuario.Qualquer interação entre a aplicação e o usuario é geralmente descrita como use-case.Como arquiteto,você começa a partir do user-case pra ter uma idéia clara das funções que devem estar disponiveis para o usuario na aplicação.

Sua próxima tarefa é simplesmente mapear funções para a classe controller.

Não existem razões técnicas que o impeçam de ter uma única classe controller que englobe toda a aplicação;e da mesma forma não existem razão técnicas que o impeçam,de ter uma classe controller para cada possível requisição.

Você está agora no momento de particionar o conjunto de funções num número balanceado de classes controller.Como você faz isso,depende das funções e mais o mais importante,da visão da aplicação que se origina do user-case.Como via de regra,você deve se preocupar em ter uma classe controller para cada entidade significante na solução da sua aplicação.

Num site comercial,é comum você encontrar use-cases que precisem de operações CRUD (Create,Read,Update,Delete) em clientes,pedidos,detalhes do pedido, e faturas.Você pode então iniciar com um OrderController para permitir que usuarios criem um novo pedido,assim como atualizar ou deletar pedidos.Fazendo isso,você deve estar focado nas necessidades da camada de apresentação,e colocar de lado,como irrelavente no momento,as necessidades da entidade modelo da camada de negócios.

Se você lida com pedidos,você provavelmente também lida com detalhes do pedido e produtos.Porém,apesar de Pedidos,Detalhes do pedido,e produtos serem bons candidatos a se tornarem membros do modelo de entidades (ou domain model,se você aplicar a metodologia domain-driven),somente Pedidos faz sentido como inspirador da criação de uma classe controller.A partir da perspectiva da interface de usuario,na verdade,um usuario irá enviar comandos somente para criar,atualizar ou deletar pedidos.Nesse caso,é OK ter um OrderController,mas não é OK ter um OrderDetailsController.Uma regra simples é a seguinte.

Ter um contoller para cada entidade de negócio que é diretamente exposta na camada de apresentação.

Esse poder ser apenas o primeiro passo,no entanto.

Suponha que um dos use-cases determine que você deva fazer com que os usuarios possam visualizar faturas.Um InvoiceController seria então util para servir as necessidade do usuario.Num site comercial,no entanto,provavelmente você vai disponibilizar uma seção de back-office para controle administrativo,como processamento de pedidos e faturas.Nesse caso,pode ser util tem uma classe controller distinta para suportar operações de back-office para pedidos e faturas.Outra regra simples é a seguinte:

Tenha uma classe controller para cada entidade da camada de negócio que é exposta diretamente na camada de apresentação e pra cada contexto operacional.

No fim das contas,o mapeamento de funções para controllers,e o subsequente mapeamento de métodos para controllers,certamente não é uma ciência exata.Porém,com a correta e sistemática aplicação dos principios da chave de design,você pode obter um design que seja aceitavel para todas as partes interessadas no projeto.O principio é o Single Responsibility Principle – SRP (Principio da Responsabilidade única).As duas regras simples citadas anteriormente fazem parte do SRP.

Mapeando comportamento de métodos

No todo, a parte mais complicada do processo de design é mapear as funções para os controllers.Depois de você ter estabelicido uma lista aceitavel de controllers,deve ficar claro quais métodos pertecem a quais controllers.Métodos de um controller são conhecidos como Actions – e o nome não poderia ser mais apropriado.Num controller,você tem um método para cada ação do usuario, o que acaba caindo na (única) responsabilidade do controller.

Como você codifica um método de um controller?O template de um método pode ser resumido no seguinte:

  • Recuperar dados de entrada – Um método pode obter argumentos de entrada de várias fontes:route values e coleções expostas pelo objeto Request.O ASP.NET MVC não impõe uma assinatura particular para métodos de um controller.Para testes,é preferivel que qualquer parametro de entrada seja recebido através da assinatura do método.Evite,se você puder métodos que recuperem parametros programaticamente através do objeto Request.Pré-condições também ajudam a garantir que não hajam valores incorretos passados nas camadas do sistema.
  • Realizar a tarefa – Nesse momento,o método realiza o seu trabalho baseado nos argumenos de entrada e nos resultados esperados.Na maioria das vezes,o método precisa interagir com a camada intermediária e qualquer dessas interações é feita através de serviços dedicados.Validações de valores calculados ocorrem também nesse estágio.
  • Preencher o View-Model – No fim da tarefa,qualquer valor que deva ser incorporado na resposta é adicinado ao view-model.O view-model pode ser um dicionario plano de key/value,ou um objeto strong-typed especifico daquela view.
  • Preparar o objeto result – Um controller não é responsável por produzir a resposta em si.Ele é responsavel,por disparar o processo que irá usar um objeto View distinto para renderizar o resultado para a saída.O método identifica o tipo da resposta (file,plain data,HTML,JavaScript,ou JSON) e prepara um objeto ActionResult de acordo.

Parece fácil de maneira geral?Bom,outro aspecto complicado é como você elabora o código que executa a tarefa.Mas isso fica para a próxima parte de design de controllers.

Até lá!

ASP.NET MVC Controllers

Entendendo Controllers

Controllers são responsáveis por respostas a requisições feitas em um website ASP.NET MVC.Cada requisição de um navegador é mapeada para um controller em particular.Por exemplo,imagine que você entre com a seguinte URL no seu navegador:

http://localhost:4656/Product/Index/3

Nesse caso,um controller chamado ProductController é chamado.Esse controller é responsável por gerar a resposta para a requisição do navegador.Por exemplo,o controller poderia retornar uma View em particular para o navegador ou poderia redirecionar o usuario para outro controller.

Veja abaixo o ProductController:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax; 

namespace MvcApplication1.Controllers
{
public class ProductController : Controller
{
//
// GET: /Products/

public ActionResult Index()
{
// Add action logic here
return View();
}

}
}

Como você pode ver acima,um controller é somente uma classe.Um controller é uma classe que deriva da classe base System.Web.Mvc.Controller.Como todo controller herda dessa classe base,um controller herda muitos métodos úteis gratuitamente.

Entendendo Actions

Uma Action é um método em um controller que é chamado quando você entra com uma URL particular no navegador.Por exemplo,a seguinte URL:

http://localhost:4656/Product/Index/3

Nesse caso,o método Index é chamado na classe ProductController.O método Index é exemplo de uma action.

Uma action deve ser um método público de um controller.Métodos C#,por padrão são privates.Perceba que qualquer método público em um controller é considerado uma action automaticamente (por isso você deve ser cuidadoso,pois esse método pode ser invocado por qualquer um no universo simplesmente digitando a URL correspondente no navegador).

Existem alguns outros requerimentos para uma action.Um método usado como action não pode ser sobreescrito.Também não pode ser static.Fora isso,você pode usar qualquer outro método como action.

Entendendo Action Results

Uma action retorna algo chamado action result.Uma action result é o que um controller retorna em resposta a uma requisição de um navegador.

O ASP.NET MVC framework contém vários tipos de action results:

  1. ViewResult – Representa HTML e markup
  2. EmptyResult – Representa resultado vazio
  3. RedirectResult – Representa redirecionamento para uma nova URL
  4. JsonResult – Representa um resultado JSON que pode ser utilizado numa aplicação AJAX
  5. JavaScriptResult – Representa um script JavaScript
  6. ContentResult – Representa um resultado em texto
  7. FileContentResult – Representa um arquivo que pode ser baixado (com conteúdo binário)
  8. FilePathResult – Representa um arquivo que pode ser baixado (com um path)
  9. FileStreamResult – Representa um arquivo que pode ser baixado (com um stream)

Todos esses Action Results herdam da classe base ActionResult.

Na maioria dos casos,uma action retorna um ViewResult.Por exemplo,o método Index abaixo retorna um ViewResult:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax; 

namespace MvcApplication1.Controllers
{
public class BookController : Controller
{

public ActionResult Index()
{
// Add action logic here
return View();
}

}
}

Quando uma action retorna um ViewResult um HTML é gerado para o navegador.O método Index acima retorna uma view chamada Index para o navegador.

Note que a action Index não retorna um ViewResult().Ao invés disso,o método View() da classe controller é chamado.Normalmente,você não retorna um action result diretamente.Ao invés disso,você chama um dos seguinte métodos,da classe controller:

  1. View – Retorna um action result ViewResult
  2. Redirect – Retorna um action result RedirectResult
  3. RedirectToAction – Retorna um action result RedirectToRouteResult
  4. RedirectToRoute – Retorna um action result RedirectToRouteResult
  5. Json – Retorna um action result JsonResult
  6. JavaScriptResult – Retorna um JavaScriptResult
  7. Content – Retorna um action result ContentResult
  8. File – Retorna um FileContentResult,FilePathResult,ou FileStreamResult dependendo dos parâmetros passados para o método

Então,se você quer retornar uma View para o navegador,você chama o método View().Se você quer redirecionar o usuario de uma action para outra,você chama o método RedirectToAction().Por exemplo,a action Details abaixo,ou mostra uma View ou redireciona o usuario para a action Index dependendo se o parâmetro ID tiver algum valor:

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
public class CustomerController : Controller
{
public ActionResult Details(int? id)
{
if (!id.HasValue)
return RedirectToAction(“Index”);

return View();
}

public ActionResult Index()
{
return View();
}

}
}

A ContentResult action é especial.Você pode usa-lo pra retornar um action result em formato de texto plano.Por exemplo,o método Index abaixo retorna o resultado como texto plano e não como HTML:

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
public class StatusController : Controller
{

public ActionResult Index()
{
return Content(“Hello World!”);
}

}
}

Quando o método Index é chamado uma View não é retornada.Ao invés disso,em seu lugar o texto plano “Hello World!” é retornado para o browser.

Se uma action retornar um valor que não seja um action result – por exemplo,uma Data ou um inteiro – então o resultado é colocado num ContentResult automaticamente.Por exemplo,quando o método Index abaixo é chamado, a data é colocada como ContentResult automaticamente:

using System;
using System.Web.Mvc; 

namespace MvcApplication1.Controllers
{
public class WorkController : Controller
{

public DateTime Index()
{
return DateTime.Now;
}

}
}

O ASP.NET MVC converte o objeto DateTime pra uma string e coloca o resultado num ContentResult automaticamente.O navegador recebe a data como texto plano.

É isso aí pessoal até apróxima!
Qualquer dúvida deixem comentários que responderei assim que possível.

ASP.NET MVC Entendendo Action Filters

Entendendo Action Filters

Um Action Filter é um atributo que você pode aplicar a uma Action de um controller,ou a um controller diretamente – o que modifica a maneira como essa action é executada.O framework MVC ja inclui muitos Action Filters

  • OutputCache – Esse action filter coloca o resultado de uma action em cache por um tempo determinado
  • Handle Error – Esse action filter manipula erros disparados durante a execução da action de um controller
  • Authorize – Esse action filter permite a você restringir acesso a um usuario ou role em particular

Você pode também criar seu próprio action filter.Por exemplo,você pode querer criar seu próprio action filter para implementar um sistema de autenticação personalizado.Ou,você pode querer criar um action filter que modifique a viewdata retornado por uma action de um controller.

Usando um action filter

Um action filter é um atributo.Você pode aplicar a maioria dos action filters para uma action ou diretamente para um controller inteiro.Por exemplo,o DataController abaixo contém uma action chamada Index que retorna a data atual.Essa action está decorada com o action filter OutputCache .Esse action filter faz com que o valor retornado pela action seja colocado em cache por 10 segundos.

using System;
using System.Web.Mvc; 

namespace MvcApplication1.Controllers
{
public class DataController : Controller
{
[OutputCache(Duration=10)]
public string Index()
{
return DateTime.Now.ToString(“T”);

}
}
}

Se você chamar repetidamente a action Index digitando a URL /Data/Index na barra de endereços do seu navegador e pressionando o botão de refresh varias vezes,você verá o mesmo horário durante 10 segundos.A saída da action Index é colocada em cache durante 10 segundos (figura 1):

No exemplo acima,um unico action filter – o OutputCache – é aplicado ao método Index.Se você precisar,você pode aplicar vários action filters diferentes a mesma action.Por exemplo,você pode querer aplicar os action filters OutputCache e HandleError para a mesma action.

No exemplo acima,o action filter está sendo aplicado diretamente na action Index,mas você também poderia ter aplicado diretamente ao controller.Nesse caso,todas as actions deste controller teriam suas saídas colocadas em cache durante 10 segundos.

Os diferentes tipos de filters

O ASP.NET MVC suporta quatro diferentes tipos de filters:

  1. Authorization filters – Implementa o atributo IAuthorizationFilter
  2. Action filters – Implementa o atributo IActionFilter
  3. Result filters – Implementa o atributo IResultFilter
  4. Exception filters – Implementa o atributo IExceptionFilter

Os filters são executados na ordem listada acima.Por exemplo,authorization filters são sempre executados antes de action filters e exception filters são sempre executados após qualquer outro tipo de filter.

Authorization Filters são usados para implementar autenticação e autorização para actions de um controller.Por exemplo,o Authorize filter é um exemplo do Authorization Filter.

Action Filters contém lógica que é executada antes e depois que a action de um controller é executada.Você pode usar um action filter,por exemplo,para modificar a ViewData que uma action retorna.

Result Filters contém lógica que é executada antes e depois da execução de um View Result.Por exemplo,você pode querer modificar um ViewResult um pouco antes da view ser renderizada para o navegador.

Exception Filters são os últimos tipo de filter que são executados.Você pode usar exception filters para tratar erros disparados pela suas actions ou pelo resultado das suas actions.Você também pode usa-lo para criar um log de erros.

Cada tipo diferente de filter é executado numa ordem em particular.Se você quiser modificar a ordem de execução de cada filter do mesmo tipo você pode setar a propriedade ORDER do filter.

A classe base para todos os filters é System.Web.Mvc.FilterAttribute.Se você quiser implementar um tipo particular de filter,então você precisa criar uma classe que herde dessa classe base e implemente uma ou mais das seguintes intefaces:IAuthorizationFilter,IActionFilter,IResultFilter ou IExceptionFilter.

<h3>A classe base ActionFilterAttribute</h3>

Pra facilitar a sua vida quando você quiser implementar um filter próprio,o ASP.NET MVC inclui uma classe base <em>ActionFilterAttribute</em>.Essa classe implementa as interfaces <em>IResultFilter</em> e <em>IActionFilter</em> herda da classe filter.

A terminologia aqui não é perfeitamente consistente.Tecnicamente,uma classe que herda da classe <em>ActionFilterAttribute</em> é tanto um Action Filter quanto um Result Filter.O termo Action Filter é usado para se referir a qualquer tipo de filter no ASP.NET MVC.

A classe <em>ActionFilterAttribute</em> possui os seguintes métodos que você pode sobrescrever:

  • OnActionExecuting – Esse método é chamado antes de uma action ser executada
  • OnActionExecuted – Esse método é chamado depois de uma action ser executada
  • OnResultExecuting – Esse método é chamado antes de uma action result ser executada
  • OnResultExecuting – Esse método é chamado depois de uma action result ser executada

Vamos ver como implementar esses métodos.

Criando um Action Filter de Log

Pra ilustrar como criar nosso próprio action filter,nós iremos criar um filter que registre os estágios de processo de uma action para a janela Output do Visual Studio.Segue abaixo:

using System;
using System.Diagnostics;
using System.Web.Mvc;
using System.Web.Routing; 

namespace MvcApplication1.ActionFilters
{
public class LogActionFilter : ActionFilterAttribute

{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Log(“OnActionExecuting”, filterContext.RouteData);
}

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Log(“OnActionExecuted”, filterContext.RouteData);
}

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
Log(“OnResultExecuting”, filterContext.RouteData);
}

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
Log(“OnResultExecuted”, filterContext.RouteData);
}

private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values[“controller”];
var actionName = routeData.Values[“action”];
var message = String.Format(“{0} controller:{1} action:{2}”, methodName, controllerName, actionName);
Debug.WriteLine(message, “Action Filter Log”);
}

}
}

Os métodos OnActionExecuting, OnActionExecuted,OnResultExecuting e OnResultExecuted chamam o método Log.O nome do método e a RouteData são passados para o método Log.O método Log escreve uma mensagem na janela output do Visual Studio conforme abaixo:

O HomeController abaixo ilustra como podemos aplicar o Log Action Filter para um controle inteiro.Quando qualquer das actions deste controle for chamada,(Index ou About) os estagios do processo de execução serão mostrados na janela Output do Visual Studio.

using System.Web.Mvc;
using MvcApplication1.ActionFilters; 

namespace MvcApplication1.Controllers
{
[LogActionFilter]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}

public ActionResult About()
{

return View();
}
}
}

É isso aí!Até a próxima pessoal!

ASP.NET MVC com Validação Jquery e ValidationSummary

Importante:Se você estiver usando a versão ASP.NET MVC 2 (Release Candidate 2),ela não vem com arquivo MicrosoftMvcJqueryValidation.js que vem incluído já na versão ASP.NET MVC 2 (Beta).Esse arquivo é essencial para o que é demonstrado nesse post.Por isso se não tive-lo baixe o código fonte CodePlex ASP.NET do MVC,e inclua o arquivo MicrosoftMvcJqueryValidation.js no seu projeto MVC,na pasta Scripts.Quando fizer o download do código fonte zipado,o caminho onde encontrará o arquivo é:Src/MvcFutureFiles

Uma das grandes caracteristicas do ASP.NET MVC 2.0 é o suporte a validação no cliente.Esta validação no cliente é possível com as libraries ASP.NET AJAX(MicrosoftMvcValidation.js) e Jquery(MicrosoftMvcJqueryValidation.js).Ambos,ASP.NET Ajax e Jquery funcionam bem.

Quando você usa validação ASP.NET Ajax no ASP.NET MVC,o HTML Helper ValidationSummary ajuda você a mostrar os erros quando um formulario invalido é enviado,mas quando você usa  validação Jquery no ASP.NET MVC,o HTML Helper ValidationSummary não mostra os erros de validação quando um formulario inválido é submetido.Nesse post eu vou demonstrar como fazer com que seja possível mostrar erros de validação quando um fomulário inválido é submetido usando a validação com Jquery.

Descrição

Vamos criar uma aplicação de exemplo para mostrar isso.Primeiro de tudo crie uma aplicação MVC.Depois abra o HomeController.cs e entre com o seguinte código:

public ActionResult Index()
{
return View();
}

[HttpPost]
public ActionResult Index(Student s)
{
if(!ModelState.IsValid)
return View();
return Content(“Thank you for submitting your form”);
}

Depois vamos criar uma nova classe chamada Student.cs dentro do Model e entrar com o seguinte código:

public class Student
{
[Required]
public string Name { get; set; }

[Required, Range(0, 200)]
public int? Age{ get; set; }
}

Depois vamos adicionar uma View para a action Index e adicionar o seguinte código a esta view:

<%@ Page Language=”C#” MasterPageFile=”~/Views/Shared/Site.Master” Inherits=”System.Web.Mvc.ViewPage<V
alidationSummaryAndJqueryValidation.Models.Student>” %>

<asp:Content ID=”Content1″ ContentPlaceHolderID=”TitleContent” runat=”server”>
Home Page
</asp:Content>

<asp:Content ID=”Content2″ ContentPlaceHolderID=”MainContent” runat=”server”>
<% Html.EnableClientValidation();%>
<%using(Html.BeginForm()){ %>
<%: Html.ValidationSummary() %>
<table>
<tr>
<td>
Name:
</td>
<td>
<%: Html.TextBoxFor(a => a.Name)%>
</td>
<td>
<%: Html.ValidationMessageFor(a => a.Name)%>
</td>
</tr>
<tr>
<td>
Subject:
</td>
<td>
<%: Html.TextBoxFor(a => a.Age)%>
</td>
<td>
<%: Html.ValidationMessageFor(a => a.Age)%>
</td>
</tr>
<tr>
<td colspan=”3″ align=”center”>
<input type=”submit” />
</td>
</tr>
</table>
<%} %>
</asp:Content>

Agora vamos adicionar os scripts necessários para a validação na Master Page,Site.Master:

<script src=”<%=Url.Content(“~/Scripts/MicrosoftAjax.js”)%>” type=”text/javascript”></script>
<script src=”<%=Url.Content(“~/Scripts/MicrosoftMvcAjax.js”)%>” type=”text/javascript”></script>
<script src=”<%=Url.Content(“~/Scripts/MicrosoftMvcValidation.js”)%>” type=”text/javascript”></script>

Agora vamos rodar a aplicação e você verá a seguinte tela:

Isso mostra que o ValidationSummary funcionou como esperado usando ASP.NET Ajax Validation.Agora apenas substitua o script acima pelo script com arquivos do Jquery para validação na Master Page,Site.Master:

<script src=”<%=Url.Content(“~/Scripts/jquery-1.4.1.min.js”)%>”type=”text/javascript”></script>
<script src=”<%=Url.Content(“~/Scripts/jquery.validate.js”)%>” type=”text/javascript”></script>
<script src=”<%=Url.Content(“~/Scripts/MicrosoftMvcJQueryValidation.js”)%>” type=”text/javascript”></script>

Agora rode a aplicação e você verá a seguinte tela:

Isso demonstra que o ValidationSummary não mostra os erros de validação se você usar os arquivos de validação do Jquery.Para fazer com que mostre,abra o arquivo MicrosoftMvcJqueryValidation.js e substitua:

errorClass: “input-validation-error”,

por

invalidHandler: function (form, validator) {
var ul = $(“#validationSummary ul”);
if (ul.length > 0) {
$(“#validationSummary”).addClass(“validation-summary-errors”);
$(“#validationSummary”).removeClass(“validation-summary-valid”);
ul.html(“”);
for (var name in validator.errorList)
ul.append(“<li>” + validator.errorList[name].message + “</li>”)
}
},
errorClass: “input-validation-error”,

O código acima simplesmente mostra o ValidationSummary com os erros de validação quando o evento invalidHandler é disparado.O evento invalidHandler é disparado quando um formulário inválido é enviado.Agora salve o arquivo MicrosoftMvcJqueryValidation.cs e rode a aplicação novamente e você verá que agora o ValidationSummary está funcionando como o esperado.Se você precisar processar alguma coisa quando o formulário for válido,você pode manipula-lo no evento sumbitHandler da mesma forma.

Resumo

O Html Helper ValidationSumamry é usado para mostrar um resumo de todos os erros de validação do formulário.Mas o VlaidationSummary não mostra os erros quando você usa validação cliente com Jquery.Nesse post,eu demonstrei como mostrar erros de validação no ValidationSummary mesmo quando usando validação Jquery.Espero que goste deste artigo,e até a próxima!

ASP.NET MVC 2.0 Areas

Introdução

Conforme as necessidades de uma aplicação WEB crescem,o número de arquivos associados com esta aplicação cresce rapidamente.Em uma aplicação web form,as páginas são geralmente seperadas em subpastas,com cada subpasta representando um grupo lógico destas páginas.Projetos web form podem usar qualquer estrutura de pastas para organizar os arquivos.
ASP.NET MVC trabalha por convenção,por isso a estrutura de arquivos é um pouco mais “rigida”;todas as páginas são agrupadas em subpastas da pasta raiz “Views”,com cada subpasta representando o nome de um controle na pasta Controllers.Por exemplo,o controle “Organizations”,tem uma pasta “Organizations” dentro da pasta “Views”,com todas as páginas ASPX representando as views para o controle “Organization”.Um exemplo de estruturas de pastas está na imagem a seguir:

Apesar do processo poder tambem ser um pouco customizado,a estrutura de páginas permanece rigída por causa da convenção.Uma recente mudança a essa convenção trouxe o conceito de “Areas”,que é um balanço entre a rigída configuração do framework ASP.NET MVC e a separação de componentes lógicos.A maneira mais facil de ver isto em ação é dar uma olhada na estrutura de pastas.Abaixo está o mesmo projeto de exemplo,rearranjado pra usar “INLINE AREAS”:

AREAS permitem aos projetos MVC manter a estrutura de pastas de controllers,models e views,enquanto separa os componentes lógicos uns dos outros;a implementação do“coração” do projeto está separado da AREA Organizations.AREAS de uma aplicação podem duplicar  nome de classes de controle,nome de classe de models,views,etc.Porém,cada AREA pode também compartilhar recursos na pasta “Shared”.

Você pode ver nos meus 2 exemplos acima,que a “linguistica” da estrutura de pastas mudou um pouco;primeiramente um controle Organization,depois uma organization AREA,com outro nivel de hierarquia no link(o “ManagementController”  se anexa a URL com /management).Agora requisições para /Organizations/Index são roteadas para  /Organizations/Management/Index.

Routing

O mecanismo de routing padrão do MVC entre views é por convenção.Por exemplo,na figura 1,um link para a “action” Manage iria ser gerado através do seguinte comando “Html.ActionLink”,que renderiza um hyperlink para redirecionar  para o controle Organizations no projeto principal:

Html.ActionLink(“Manage this Organization”, “Manage”,

new { controller = “Organizations”, key = 1 })

O primeiro parâmetro especifica o texto do link,os 3 ultimos parametros  especificam o action metódo a ser chamado,e os parametros da “route”,que são passados como querystring.

O conceito de AREAS muda isso um pouco,porque nós precisamos poder diferenciar a area pra qual nós queremos rotear.Isso é simples;adicione um  “key/value pair AREA” para a lista de parametros da “route”.Para rotear para nossa nova “inline area”,nós podemos usar a seguinte sintaxe:

Html.ActionLink(“Manage this Organization”, “Manage”, “Management”,

new { area = “Organizations”, key = 1 })

Informando a area especifica podemos navegar para a area correta;sem isso,o link iria mandar para o ManagementController no projeto principal,que não existe;Adicionando o parametro area=”Organizations”, faz com que as requisições seja corretamente roteadas para os controles dentro daquela area.

Mas há alguns outros passos para que isto aconteça,e requer o uso de um novo objeto chamado “AreaRegistration”.Um processo personalizado de registro deve ser criado para as AREAS,como a seguir:

public class OrganizationsAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return “Organizations”;
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
“Organizations_default”,
“Organizations/{controller}/{action}/{id}”,
new { action = “Index”, id = UrlParameter.Optional }
);
}
}

O método RegisterArea é o componente chave para fazer o registro adicionando outra “route” para a coleção de “routes” de AREA.Note que o nome da AREA “Organizations” está fixado na URL;todas as requisições prefixadas com o nome de areas são tratadas de forma diferente.

Você deve estar pensando: porque nós não podemos especificar   Organizations para a definição de “routes” na aplicação principal?Se nós tivessemos adicionado  para a tabela de “routes” padrão,e não através do contexto da area,nós ainda teríamos que ter todos os arquivos no nosso mesmo projeto,e perderíamos os beneficios da separação de Areas de projeto.

Multi-projects Area

Não suportado diretamente no ASP.NET MVC 2 nem no ASP.NET MVC ,a versão RC e beta,tambem suportam “areas” que são “projetos separados”.Um projeto MVC separado poderia ser referenciado como uma area e funcionar  da mesma maneira que uma “INLINE AREA”.A forma de se fazer é muito parecido com “INLINE AREAS”,com a execeção de algum trabalho de configuração adicional no projeto MVC.

Essas configurações adicionais precisam de uma técnica que copia o conteúdo do projeto e fazem o “deploy” dele no projeto principal,basicamente mesclando a AREA que contem o projeto externo com o projeto principal do ASP.NET MVC.O processo de “deploy” funciona sem emendas para você,e acontece automaticamente através de uma tarefa MSBUILD,como parte de futuros assemblies do ASP.NET MVC.Existe um assembly chamado Microsoft.Web..Mvc.Build.dll que faz esse processo para você.

Isso não é oficialmente suportado pela microsoft;no entanto,se você quiser tentar essa configuração,os seguintes recursos irão ajuda-lo a implementar a tarefa no seu projeto:

http://msdn.microsoft.com/en-us/library/ee307987%28VS.100%29.aspx

http://dotnetslackers.com/articles/aspnet/a-first-look-at-asp-net-mvc-2.aspx

Considerações Finais

Areas são uteis para separar conteudo,mas eu lhe recomendo,não abusar,por varios motivos.Primeiro,areas realmente aumentam o numero de arquivos do projeto.Manter o projeto reduzido dentro do possivel ajuda na manutenção.Eu não estou advogando contra AREAS,eu estou recomendando um balanço entre o tamanho do projeto e a separação lógica de conteudo.

Uma coisa legal com AREAS é que você pode configurar controles com nomes similares para as views e fazer com que o site pareça mais consistente.Por exemplo,as areas account,store, e catalogo podem ter URLS consistentes dando nomes similares aos controles e actions de cada Area.Por exemplo,seu site poderia ter o seguinte:

/Accounts/Search/Index

/Store/Search/Index

/Catalog/Search/Index

Conclusão

Areas ajudam a separar conteudo,e alteram o processo de “routing”.Areas tem suas próprias estruturas de pastas e roteam suas próprias requisições de controles para as views.Routes requerem uma novo parametro de  “AREA de “routing”,que é usado para rotear para a area correta.

Entendendo o processo de execução de uma aplicação MVC


Requisições para uma aplicação ASP.NET MVC primeiramente passam por um objeto UrlRoutingModule,que é um módulo HTTP.Esse módulo analisa a requisição e faz uma seleção de route.O objeto UrlRoutingModule seleciona o primeiro objeto route compativell a requisição atual.(Um objeto route é uma classe que implementa RouteBase,e é geralmente uma instância da classe Route).Se não forem encontradas routes,o objeto UrlRoutingModule não faz nada e deixa a requisição cair para o processamento de requisição normal do IIS ou  ASP.NET.

A partir do objeto Route selecionado,o objeto UrlRoutingModule obtém o objeto IRouteHandler que é associado com a Route do objeto.Geralmente,numa aplicação MVC,esse será uma instancia do MvcRouteHandler.A instancia IRouteHandler cria um objeto IHttpHandler e passa este para o objeto IHttpContext.Por padrão,a instancia IHttpHandler para o MVC é o objeto MvcHandler.O objeto MvcHandler então seleciona o controller que irá por último controlar a requisição.

Nota:Quando uma aplicação MVC roda no IIS7.0,nenhuma extensão de nome de arquivo é requerida pra projetos MVC.Entretanto,no IIS6.0,o handler requer que você mapeie a extensão de nome de arquivo .mvc para o ASP.NET ISAPI DLL.

O módulo e o handler são pontos de entrada para o framework MVC.Eles realizam as seguintes ações:

  • Selecionam o controller apropriado na aplicação MVC.
  • Obtem uma instancia especifica do controller.
  • Chamam o método Execute do controller.

A tabela a seguir lista os estágios de execução de um projeto MVC:

Estágio Detalhes
Recebe a primeira requisição para a aplicação No arquivo global.asax,objetos Route são adicionados para o
objeto RouteTable.
Realiza o roteamento O módulo UrlRoutingModule usa o primeiro objeto Route
compativel,na coleção RouteTable pra criar o objeto RouteData,
que é então usado pra cria um objeto
RequestContext(IHttpModule).
Cria um request Handler MVC O objeto MvcHandler usa a instancia do RequestContext
para identificar o objeto IControllerFactory(geralmente
uma instancia da classe DefaultControllerFactory)pra criar
a instancia do controller.
Executa o controller A instancia do MvcHandler chama o método Execute do Controller
Invoca a ação A maioria dos controllers herdam da classe base Controller.
Para esses controles,o objeto ControllerActionInvoker
que é associado com o controller determina qual método
de ação da classe controller chamar,e depois chama o método.
Executa o resultado Um método de ação comum pode receber entradas do usuário,
preparar a resposta de dados apropriada e depois executar o
resultado retornando um tipo de resultado.Os tipos de resultado
que podem ser executados,são os seguintes:
ViewResult
(que renderiza uma view e é o mais frequentte
tipo de resultado utilizado);RedirectToRouteresult,
RedirectResult,ContentResult,JsonResult, e  EmptyResult.

MVC Visão geral

MVC Visão Geral

A arquitetura MVC separa a aplicação em 3 principais componentes:o model,a view e o controller.O ASP.NET NVC framework oferece uma alternativa aos web forms ASP.NET.O framework MVC é leve,assim como aplicações baseadas em Web Forms é integrado com elementos do ASP.NET como master pages e autenticações baseadas em membership.O  framework MVC está definido no namespace System.Web.Mvc.

MVC é um padrão de design que muitos desenvolvedores já estão familiarizados.Alguns tipos de aplicação se beneficiam do MVC framework.Outros irão continuar com o tradicional modelo baseado em web forms e postbacks.Outros tipos de aplicação irão combinar os dois modelos;nenhum modelo elimina o outro.

O framework MVC inclue os seguintes componentes:

  • Model: Model são as partes da aplicação que implementam a lógica no dominio dos dados.Geralmente,objetos do model recuperam e armazenam o estado no banco de dados.Por exemplo,um objeto produto pode recuperar dados do banco,operar neste,e depois escrever a informação atualizada de volta para a tabela produtos no SQL server.

Em aplicações pequenas,o modelo geralmente é uma separação conceitual em vez de fisica.Por exemplo,se a aplicação somente le um conjunto de dados e manda este para a view,a aplicação,não tem uma camada model  fisica e classes associadas.Nesse caso,o conjunto de dados,representa o objeto model.

  • Views:View são componentes que mostram a interface de usuário.Geralmente,esta é criada a partir do modelo de dados.Um exemplo seria view de edição de uma tabela de produtos que mostra textbox,drop-down lists e checkboxes baseado no estado atual do objeto produtos.
  • Controllers:Controllers são componentes que controlam a interação,trabalhando com o modelo e por último selecionando uma view que mostrará a interface.Numa aplicação MVC,a visão somente mostra a informação;o controller controla e responde a interação do usuário.Por exemplo,o controller controla valores querystring e transmite esses valores para o modelo,que em turnos consulta o banco, passando estes valores.

O padrão MVC ajuda você a criar aplicações que separam diferentes aspectos da aplicação.O padrão especifica onde cada tipo de lógica deve se localizar na aplicação.A lógica de interface pertence a view.A lógica de entrada pertence ao controller.A lógica de negócio pertence ao modelo.Essa separação ajuda você a administrar complexidades quando você cria a aplicação,porque permite você focar em um aspecto de implementação individualmente.Por exemplo,você pode focar na view sem depender da lógica de negócio.

Além da de administrar a complexibilidade,o padrão MVC torna fácil o teste de aplicações, mais fácil do que o modelo baseado em web forms.Por exemplo,numa aplicação web form,uma única classe pode ser usada para mostrar a saída e responder a entradas do usuário.Escrever testes automatizados para aplicações em web forms pode ser complexo,porque para testar uma página individual,você deve instanciar a classe Page,todos os seus controles filho, e classes dependentes da aplicação.Como muitas classes são instanciadas para rodar a página,pode ser dificil escrever  testes que foquem exclusivamente em partes individuais da aplicação.Testes para aplicações em web form  podem por isso ser mais dificil de implementar do que  testes em uma aplicação MVC.Mais ainda,testes em aplicação web form requerem um servidor web.O framework MVC desacopla os componentes e faz uso pesado de interfaces,que tornam possivel testar componentes individuais isolados do resto do framework.

O desacoplamento entre os 3 principais componentes da aplicação MVC também oferece desonvolvimento paralelo.Por exemplo,um desenvolvedor pode trabalhar na view,um segundo desenvolvedor pode trabalhar na lógica do controller,e um terceiro pode focar na lógica de negócio no model.

Decidindo quando criar uma aplicação MVC

Você pensar cuidadosamente em implementar uma aplicação usando o MVC framework ou o modelo baseado em Web forms.O framework MVC não substitui o modelo de web forms;

Antes de decidir em usar o framework MVC ou o modelo de web forms para um web site,leve em consideração as vantagens de cada método.

Vantagens em usar o framework MVC

Ofece as seguintes vantagens:

  • Torna facil administrar a complexibilidade dividindo a aplicação em model,view,controller.
  • Não usa viewstate .Isso torna o MVC ideal para desenvolvedores que querem controle total sobre o comportamento da aplicação.
  • Oferece melhor suporte para ‘test-driven development’(TDD)
  • Funciona bem para aplicações que são suportadas por um time grande de desenvolvedores e web designers que precisam de alto grau de controle sobre o comportamento da aplicação.

Vantagens em usar Web Forms

Oferecem as seguintes vantagens:

  • Suporta um modelo de eventos que preserva  o estado HTTP.
  • Usa um modelo de controle de página que adiciona funcionalidade para páginas individuais.
  • Usa viewstate,que pode tornar a administração de estados mais facil
  • Funciona bem em times pequenos de desenvolvedores e designers que querem tirar vantagem do grande número de componentes disponiveis para o rápido desenvolvimento de uma aplicação.

Download ASP.NET MVC

Veja também:
Entenda o processamento de uma aplicação MVC
Valeu pessoal.Até a próxima!