ASP.NET MVC - Quando utilizar ViewBag, ViewData e TempData ?

by Felipe Oriani 6. setembro 2011 05:17

Olá pessoal, neste post farei uma breve explicação de como trabalhar com mecanismos de transferência de dados no asp.net mvc, que existe uma certa semelhança entre eles mas existem recomendações de uso quanto ao cenário em que se aplica. Esta é uma questão que sempre vejo em alguns fóruns e listas de discussões, portanto resolvi escrever este post para entrar em um detalhe maior.

A ViewBag, ViewData e TempData são propriedades da classe base ControllerBase e ViewPage e basicamente são utilizados para transferir dados entre Controllers, Actions e Views.

ViewBag e ViewData

As propriedades ViewBag e ViewData, tem o mesmo objetivo, portar dados do Controller para uma View, porém a ViewData (do tipo ViewDataDictionary que implementa a interface IDirectionary<string, object>) é um dicionário de chaves/valores onde você determina uma chave string é possível aplicar um valor qualquer como object. A ViewBag é um wrapper para a ViewData, e esta por sua vez, utiliza recursos do .Net Framework 4.0 tendo pro definição seu  tipo como dynamic, o que nos permite criar propriedades em tempo de execução, fornecendo tipagem além de elegância. Ambas as propriedades são preenchidas em Actions (veja o método View da classe Controller do Asp.Net MVC http://aspnet.codeplex.com/SourceControl/changeset/view/68345#266451) e ficam disponíveis na View a ser renderizada e são recomendados para os cenários:

·         Preencher controles de seleção (combox, listbox, lista de checkboxes, lista de radiobuttons, etc..).

·         Transferir pequenos valores de dados (tipos primitivos).

·         Informações extras (exemplo: dados do usuário conectado a aplicação).

É importante destacar que devemos ter um cuidado maior quando utilizamos estas propriedades, pois se na View o código tentar acessar um valor não definido na ViewData ou ViewBag uma exceção será lançada na página. Quando utilizamos a ViewData, por estarmos utilizando um dicionário com uma chave em string e valor em object, é necessário realizar unboxing para o tipo correto do valor quando precisarmos acessar algo específico do objeto. Já com a ViewBag o unboxing torna-se desnecessário porém o mesmo cuidado quanto a existência de uma propriedade deve ser levado em consideração.

Um exemplo do uso da ViewData e ViewBag:

public ActionResult Index() {

   ViewData["Produto"] = "Guitarra";

   ViewBag.Cliente = "Felipe Oriani";

   return View();
}

Acessando estas informações na view:

Cliente: @ViewBag.Cliente

<br/><br />

Produto: @ViewData["Produto"]

<br/><br/>

Cliente (ViewData): @ViewData["Cliente"]

Como dito anteriormente, a ViewBag utiliza a ViewData para armazenar as propriedades, portanto as propriedades dinâmicas que são criadas na ViewBag tornam-se acessíveis na ViewData, mas recomenda-se o uso direto da ViewBag, uma vez que o projeto utilize a versão 3 do Asp.Net MVC.


TempData

Esta propriedade está presente também na classe ControllerBase e é do tipo TempDataDictionary (que implementa a interface IDirectionay<string, object) que trata-se de um dicionário de chave/valor. Seu uso é semelhante à ViewData, porém o objetivo principal da TempData são dados temporários que podem ser transportados para um novo contexto Http. Cenários recomendados:

·         Mover um objeto para outra action.

·         Manter algum estado quando um Redirect é realizado.

 

Vamos a um exemplo simples:

public ActionResult Direcionar()
{
   TempData["Tecnologia"] = "ASP.NET MVC"; 
   return RedirectToAction("Index");
}

Na view Index, conseguimos recuperar este valor, da mesma forma que fazemos com a ViewData, porém acessando a TempData.

TempData: @TempData["Tecnologia"]

Acessando diretamente a action Index, a TempData virá nula pois não foi setado. No caso de acessar a action Direcionar vocÊ será redirecionado para a index após ter criado uma chave na TempData, sendo assim, após o redirect do protocolo http para a action Index, um valor foi persistido no TempData (internamente em Session) o que permite o acesso desta chave no destino (lembrando que após a finalização da execução do Request, a TempData é liberada). Veja a imagem abaixo realizando um Debug ao tentar executar a Action 'Direcionar'.

 

Bem pessoal, por hoje é isso, algo simples e fácil de utilizar-se no asp.net mvc.

Um abraço

Tags: ,

ASP.Net MVC

ASP.NET MVC 3, IDependencyResolver com Microsoft Unity

by Felipe Oriani 21. julho 2011 11:29

Olá pessoal, dando continudade aos artigos sobre injeção de dependência (e inversão de controle), neste post pretendo mostrar de forma rápida como trabalhar com um container de dependências no ASP.NET MVC. Conforme os artigos anteriores, os exemplos utilizarão o Microsoft Unity.

Até a versão 2 no ASP.NET MVC, para resolver dependencias em nossos Controllers era necessário modificar a Controller Factory padrão (responsável por criar os controllers) do Asp.Net MVC herdando da classe DefaultControllerFactory e sobreescrevendo o método GetControllerInstance. Já na versão 3, este processo ficou mais fácil pois foi incorporada uma nova interface chamada IDependencyResolver que visa resolver dependencias de Controllers (onde podemos utilizar um container de dependencias para isto), veja sua declaração:

public interface IDependencyResolver {
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}

Conhecendo esta interface, podemos realizar uma implementação básica junto a um container do Unity:

public class UnityDependencyResolver : IDependencyResolver
{
	private IUnityContainer container;

	public UnityDependencyResolver(IUnityContainer container)
	{
		this.container = container;
	}

	public object GetService(Type serviceType)
	{
		if (!container.IsRegistered(serviceType)) {
			if (serviceType.IsAbstract || serviceType.IsInterface) {
				return null;
			}
		}
		return container.Resolve(serviceType);
	}

	public IEnumerable<object> GetServices(Type serviceType)
	{
		return container.ResolveAll(serviceType);
	}
}

Uma vez tendo uma implementação desta interface e um container com todas as dependencias registradas, podemos seta-la como a “resolvedora” de dependencias em nosso projeto no arquivo global.asax no evento Application_Start, veja abaixo:

//declaração de nosso container de dependencias
private static UnityContainer _container;

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();
	
    // criando nosso container de dependencias e registrando uma dependencia de exemplo.
	_container = new UnityContainer();
	_container.RegisterType(typeof (IPersonRepository), typeof (PersonRepository));
	
	RegisterGlobalFilters(GlobalFilters.Filters);
	RegisterRoutes(RouteTable.Routes);
	
    //modificando o DependencyResolver para a nossa customização passando o container.
	DependencyResolver.SetResolver(new UnityDependencyResolver(this._container));
}

protected void Application_End() 
{
    // ao finalizar a aplicação, libera o container
    if (_container != null)
	    _container.Dispose();
}

No exemplo acima, criamos um container do unity e registramos um dependencia de um repositorio simples como exemplo. Na última linha, do método Application_Start, informamos ao DependencyResolver através do método SerResolver que nossa classe UnityDependencyResolver (implementação de IDependencyResolver) será nossa “resolvedora” de dependencias. Com isso, quando um controller necessitar de um dependencia (seja via construtor ou propriedade) ela será resolvida pela DependencyResolver.

Veja abaixo uma imagem do momento que um controller é instanciado e sua dependencia sendo resolvida com um repositório simples.

 IDependencyResolver com Microsoft Unity

Repare que o controller depende do tipo de uma interface que está registrada no container do unity e o tipo concreto que é instanciado é o respectivo ao registro no container.

Caso você queira dar uma olhada nos fontes do ASP.NET MVC 3, e ver como a controller factory utiliza uma instância de IDependencyResolver para trabalhar, clique aqui e entenda melhor como este processo funciona.

Espero que gostem e ajudem em seus projetos.

Abraços.

Tags: , ,

ASP.Net MVC | Padrões de Projetos

ASP.NET MVC 3 e HTML

by Felipe Oriani 5. janeiro 2011 04:34

Olá amigos, neste post de hoje vou deixar dicas simples mas útil que veio complementar o asp.net mvc 3. Pelo fato de o asp.net mvc 3 ainda estar na versão RC2, podem haver mudanças em sua versão final. O pequeno artigo de hoje, trata-se de métodos e atributos para se trabalhar com HTML.

O Método Html.Raw

Este é um novo método de extenção na classe HtmlHelper com a assinatura IHtmlHelper.Raw(string value) que tem o intuito de exibir um conteúdo em HTML de forma segura, ou seja, uma string com conteúdo formatado em HTML. O método é útil pois quando utilizamos a Razor View Engine, por padrão o Response já imprime o conteúdo de strings em unencoded, então o método nos ajuda a enviar conteúdo Html para ser interepretado ao browser através de código server-side dinâmico. Veja um exemplo de uso:

 

@{ 
   var texto = "<p>Este é um texto para ser exibido em <strong>HTML</strong> puro.</p>";
}

Conteúdo da váriavel: 
@texto

<br><br>

Conteúdo da váriavel (Raw):
@Html.Raw(texto)

 

O output disso, seria desta forma:

 

Conteúdo da váriavel:  &lt;p&gt;Este &#233; um texto para ser exibido em &lt;strong&gt;HTML&lt;/strong&gt; puro.&lt;/p&gt;

<br><br>

Conteúdo da váriavel (Raw): <p>Este é um texto para ser exibido em <strong>HTML</strong> puro.</p>

 

Ou seja, o método gera o Html da forma correta, enquanto a primeira abordagem transforma o conteúdo da string em HTML seguro.

O Atributo AllowHtml

Outros recurso interessante e simples que será introduzido no Asp.Net MVC 3, é a possibilidade de deixar de forma explícita que uma propriedade de nosso model permite conteúdo em formato Html. Esta possibilidade da-se pelo atributo AllowHtmlAttribute. Um exemplo simplista disso:

 

using System.Web.Mvc;

public class Produto {
   //outras propriedades
   [AllowHtml]
   public string Detalhes { get; set; }
}

 

Tendo isso em mente, quando formos efetuar um bind deste model, o asp.net mvc já saberá que aquela propriedade pode possuir contéudo em html e irá desabilitar o "HTML injection protection" que efetua uma validação contra post de conteúdo html para o servidor.

Bem, era isso o que gostaria de passar hoje, espero que seja útil a alguem.

Abraços

Referência: http://www.asp.net/learn/whitepapers/mvc3-release-notes#0.1__Toc274034209

Tags: ,

ASP.Net MVC

ViewModel Dynamic em ASP.Net MVC 3

by Felipe Oriani 9. setembro 2010 05:42

Olá amigos, neste post vou abordar um novo recurso que estará disponível no Asp.Net MVC 3 (atualmente no Preview 1) que é a possibilidade de termos propriedades dinâmicas no ViewData (ViewModel no Asp.Net MVC 3). Antes de abordar o tema principal do post, vamos entender como o ViewData trabalhou trabalha no Asp.Net MVC.

Todo controller em ASP.Net MVC deve herdar diretamente (por default) ou indiretamente de uma classe base chamada “Controller” que está debaixo de System.Web.Mvc para que o framework consiga entender que tal classe é um Controller. Como todos sabem, controllers possuem métodos que podem ser chamados de “Actions” que definem o tipo e qual View será renderizada, e em alguns momentos desejamos passar alguma informação para esta View. Para isso, uma propriedade publica na classe Controller chamada ViewData é responsável por enviar informações para que possam ser acessadas na View.

Esta propriedade ViewData que é do tipo  IDictionary<string, object> (classe concreta ViewDataDictionary) é um objeto do que através de uma chave (string) retorna qualquer objeto (object). Por um lado, isto facilitou muito a vida dos desenvolvedores pois podemos passar qualquer informação para a View sendo que o tipo Object é o tipo básico pra qualquer objeto em .Net. Por outro lado gerou conflitos, pois além de não ser type safe (ou tipado, ter a garantia que aquela instância é de determinado tipo, havendo a necessidade de realizar uma conversão), alguns erros podem passar despercebidos como os índices podem ser “strings mágicas”.

Com isso, foi implementado uma nova propriedade chamada ViewModel na classe controller, que é do tipo dynamic (novo recurso disponível a partir do .Net Framework 4.0) que permite que você defina propriedades em tempo de execução e o compilador as resolve para nós definindo o tipo, ou seja, quando fazíamos:

 

ViewData["Mensagem"] = "Olá Mundo ViewData";

 

Agora podemos fazer:

 

ViewModel.Mensagem = "Olá Mundo ViewData";

 

Perceba que ViewModel é outra propriedade, ou seja, ViewData ainda existe porém não contém recursos de type safe, já a ViewModel pelo fato de ser do tipo dynamic, conseguimos definir uma propriedade qualquer e aplicar um valor, como neste exemplo onde definimos uma propriedade chamada “Mensagem” e aplicamos a string  “Olá Mundo ViewModel” fazendo com que dinamicamente o .Net Framework identifique e a crie para nós tal propriedade de tal tipo; Na View conseguimos recuperar ambos os valores tanto como ViewData como ViewModel.

A vantagem disso é que agora temos uma propriedade específica para aplicar ViewModel (boa prática comum até a versão 2.0 do Asp.Net MVC). Podemos utilizar o ViewModel com propriedades dinâmicas a fim de ter maior segurança que tal tipo será retornado durante o processo de execução. Para ilustrar vamos a um exemplo.

Imagine que em nosso projeto temos uma página que irá listar os produtos de um catálogo. Para tanto precisaremos de uma classe produto em nosso Modelo, que defini da seguinte forma:

public class Produto
{
   public string Nome { get; set; }
   public decimal Valor { get; set; }
 
   public Produto(string nome, decimal valor)
   {
      this.Nome = nome;
      this.Valor = valor;
   }
}

Em seguida desejamos listar produtos em nossa página, então poderíamos fazer algo do tipo em uma Action:

 

public ActionResult Index()
{
   ViewModel.Titulo = "Produtos do Catálogo"; 
   ViewModel.Produtos = ObterProdutos();
 
   return View();
}

 

No código acima, definimos uma propriedades chamada Produtos que é inicializada a partir de um método chamado ObterProdutos() que retorna um IEnumerable<Produto>. Em nossa View, conseguimos recuperar a propriedade Produtos e iterá-la pelos objetos:

 

<h2><%: View.Titulo %></h2>
   
<% foreach (var produto in View.Produtos) { %>
   <%: produto.Nome %> - <strong><%: produto.Valor.ToString("C2") %></strong><br />
<% }%>

 

O resultado:

  

 

Bem, era isso que gostaria de mostrar.

Em minha opinião este recurso irá facilitar muito, pois não vejo mais a necessidade de ficar criando ViewModel para cada View.

Espero que gostem!
Abraços

 

Referências:
http://haacked.com/archive/2010/08/02/dynamic-methods-in-view-data.aspx
http://www.asp.net/mvc

Download do exemplo: Mvc3Dynamic.zip (319,37 kb)

Tags: , , ,

ASP.Net MVC

Upload de Arquivos com Asp.Net MVC

by Felipe Oriani 8. setembro 2010 04:32

 

Olá amigos, neste post vou falar um pouco de como trabalhar com arquivos em Asp.Net MVC ou seja, fazer upload. Vou tentar ser direto e prático.

Vamos ao Visual Studio (2008 ou 2010) e crie uma nova aplicação Asp.Net MVC 2 , e vamos ao código de nosso controller Home e crie uma action (métodos) chamada Upload, para receber como no código abaixo:

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

Se você possui algum conhecimento em Asp.Net MVC, você deve saber que este framework trabalha sobre um sistema de rotas, que toma como base Actions de um Controller. Tendo isso em mente, podemos criar uma view na pasta Views/Home chamada Upload (arquivo Upload.aspx), que será a renderização[3] padrão desta Action. Ao criar esta View, adicione o código abaixo:

<h2>Upload de Arquivo</h2> 
    <% using (Html.BeginForm("Upload", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" })) { %>
        <input type="file" id="arquivo" name="arquivo" />
        <input type="submit" value="Upload" />
    <% } %>

O código acima renderiza um formulário simples para upload de arquivo, dizendo que a tag <form /> será submetida a um action chamada Upload no controller Home pelo método Post junto ao atributo enctype que especifica o tipo de conteúdo que será enviado neste formulário.

Você deve estar se perguntando, como que este formulário irá submeter informações para a mesma action que a renderizou ? De fato, pode parecer mas não é devido a sobrecarga de métodos que podemos fazer .Net. Em nosso controller Home, vamos adicionar outro método que irá receber este arquivo, porém com algumas diferenças, veja no código abaixo:

[HttpPost]
public ActionResult Upload(HttpPostedFileBase arquivo)
{
     if (arquivo != null)
     {
          arquivo.SaveAs(Server.MapPath("~/arquivos/") + Path.GetFileName(arquivo.FileName));
          return RedirectToAction("Index");
     }
     return View();
 }

Repare que este método possui uma assinatura diferente do anterior (aplicando a sobrecarga de métodos). O método possui um atributo chamado HttpPost, que implica que aquela Action pode ser invocada a partir do método Post, além de receber também a instância de um objeto HttpPostedFileBase que é o objeto correspondente para nosso arquivo no formulário. 

Com isso testando se algum arquivo foi realmente postado (verificando se o objeto não é nulo) e salvamos este em algum local (estou salvando em uma pasta chamada “arquivos” em projeto, em seguida redirecionamos o usuário para a view Index, do contrário a view de Upload é renderizada novamente. 

Obs: Não estamos fazendo algum tipo de validação mas isso seria possível através de algumas propriedades que o objeto arquivo (de HttpPostedFileBase) disponibiliza. 

Bem, de maneira simples vimos como podemos fazer upload em Asp.Net MVC, e com isso temos várias possibilidades como por exemplo, validar upload de determinados tipos de arquivo, arquivos compactados, imagens a serem trabalhadas, entre outros.

 

Espero que ajude alguém
Abraços

Referências:
http://cavalcante.net/
http://www.asp.net/mvc

 

 

 

MvcUpload.zip (300,73 kb)

Tags: , ,

ASP.Net MVC | C#

ASP.Net MVC - Desenvolvendo para o "Core" da Web

by Felipe Oriani 21. maio 2010 12:23

Olá a todos! Algum tempo atrás a Microsoft já havia anunciado a versão MVC de sua plataforma de desenvolvimento web, o ASP.Net MVC. Esta por sua vez não veio como um sucessor da atual versão do ASP.Net WebForms e sim como uma alternativa tendo suas diferenças. Ambas as tecnologias são produtivas e eficientes e dizer que uma é melhor ou deixa de ser que a outra é pura falta de conhecimento.

Atualmente estamos na versão 2.0 do ASP.Net MVC, e espero que a Microsoft continue promovendo ambas as versões do ASP.Net, MVC e Webforms. Você pode fazer o download da versão 2.0 aqui e instalar, lembrando que o ASP.Net MVC contém compatibilidade apenas com as versões 2008 ou superior do Visual Studio.

Uma das principais vantagens que vejo no MVC perante ao Webforms, é que o primeiro foi desenvolvido diretamente para trabalhar já aplicando padrões de projetos (design patterns) e desenvolvimento orientado a testes (TDD) enquanto no segundo está mais focado no desenvolvimento orientado a componentes (entenda, como server controls) e eventos. Devemos ter em mente que tanto o ASP.Net MVC como o Webforms, contém o mesmo Núcleo, que é o ASP.Net CORE, o que permite o uso de diversos recursos que aplicamos em webforms, como chaching, logging, etc.

No ASP.Net MVC todo o output da aplicação web e todo o controle de estado ficam por conta do desenvolvedor (ou time de desenvolvimento) que por sua vez recomenda-se estar maduro em relação as Web Standards assim como em ASP (3.0), PHP e outras tecnologias. Dizer que isso é uma falta de produtividade é no mínimo imaturidade em relação a inovação tecnológica, pois em minha visão temos uma leve vantagem em relação ao ASP.Net Webforms, por exemplo: componentes de interfaces como grids, inputs, seletores, menus, etc...  podemos encontrar aos montes como extenções da JQuery, ExtJS, e outras bibliotecas client-side (javascript ou css) tornado as mais fáceis de se implementar em uma aplicação ASP.Net MVC pelo fato de termos controle do output, sem precisar se preocupar com os imensos campos conhecidos como ViewState que persistem o estado de cada server control (pecando um pouco na performace e output) em um webform.

Para quem estava acostumado a ASP.Net Webforms em montar suas URLs diretamente no sistema de arquivos, o cenário muda um pouco no ASP.Net MVC que por sua vez, utiliza um esquema de tabela de rotas que monta as URLs diretamente ligada aos Controllers que por sua vez retornam para o browser renderizar uma View, podendo passar um Model, mantendo URLs mais amigáveis aos usuários além de ter maior facilidade para integrar com otimizadores de buscas e SEO.

A versão 2.0 ainda trás novos recursos como maior suporte a Areas (que na versão 1.0 era possível porém exigia certo esforço do desenvolvedor para integrar), validação do Model em Client e Server side acesso assíncrono aos controllers, integração com sub-sessões (através do método Html.RenderAction que permite que a view renderize outra Action [outra View]) como resultado HTML, entre outros.

 

Existe um projeto demonstrativo no codeplex chamado MVC Music Store que aplica padrões de projetos junto a uma aplicação ASP.Net MVC 2.0. Trata-se de uma pequena loja virtual com um carrinho de compras implementado em C# e Entity Framework 4.0. Acesse o link do projeto em http://mvcmusicstore.codeplex.com/, faça o download e bons estudos.

 

 

 

Espero que gostem e bons estudos.

Abraços

Tags: , , ,

.Net Framework | ASP.Net MVC | Padrões de Projetos

Sobre

Sou Felipe Oriani e trabalho com desenvolvimento web desde 2004, com tecnologias Microsoft como Asp e Asp.Net utilizando as linguagens C# e Vb.Net. Bacharel em Ciência da Computação pela Escola de Engenharia de Piracicaba,  MCTS (.Net Framework 3.5, ASP.NET Applications). Conheça um pouco mais sobre meu CurrículumVeja mais 

Social

profile for Felipe at Stack Overflow, Q&A for professional and enthusiast programmers

Selos

MCTS .Net Framework 3.5, ASP.NET Developer

MCP - Microsoft Certified Professional