ASP.Net MVC – View Model Pattern – Quando e como utilizar?

No desenvolvimento em ASP.Net utilizando o framework MVC é muito comum o uso do pattern View Model, esse pattern proporciona uma melhor organização do código e gestão dos dados utilizados na View, confira em quais situações ele é utilizável e algumas maneiras de como aplicá-lo.

A necessidade da utilização do pattern View Model surge na maioria dos projetos ASP.Net MVC, para os iniciantes costuma causar alguma confusão, porém é muito útil e poupa um bom trabalho.

O conceito de View Model não limita-se apenas para o ASP.Net MVC, você poderá encontrar referências sobre View Model para padrões MVC, MVP e MVVM, que por sua vez é implementado em tecnologias como ASP.Net, Silverlight e WPF.

Este artigo é dedicado para o entendimento do padrão View Model utilizando ASP.Net MVC.

O que é um ASP.Net MVC View Model?

No ASP.Net MVC os View Models nos permitem modelar várias entidades a partir de um ou mais modelos em um único objeto, eu gosto de usar como exemplo a comparação de View Models com uma DTO, pois ambas são soluções que foram projetadas para centralizar um conjunto de dados de diversas fontes assim evitando a necessidade de realizar várias chamadas para se obter todos os dados necessários e evitar a necessidade de alterar um modelo de domínio para realizar o transporte de algum dado específico.

Resumindo, um View Model representa um conjunto de uma ou mais Models e outros dados que serão representados em uma View que necessita exibir determinado conjunto de informações. A imagem abaixo ilustra o conceito de um View Model:

ASP.Net  MVC View Model Pattern

Utilizando uma View Model dedicada contendo a Model de domínio

Imagine que estamos desenvolvendo uma aplicação web de uma loja virtual onde possuímos a classe Produto:

public class Produto
{
    public string Nome { get; set; }
    public decimal Valor { get; set; }
}

Porém na View de carrinho de compras além das informações contidas na classe Produto é necessário exibir uma mensagem e o valor total do carrinho para vários produtos. O que fazer? Modificar a classe Produtos para conter essas informações?

Modificar a classe Produto não seria uma boa alternativa, afinal esses dados adicionais não fazem sentido pertencerem a entidade Produto, são dados pertinentes a View de carrinho de compras.

É nesse momento que o pattern View Model entra em ação para resolver esse problema de design. Criaremos então uma classe que irá prover dados para esta View e essa classe será uma View Model de carrinho de compras.

public class CarrinhoComprasViewModel
{
	public IEnumerable Produtos { get; set; }
	public decimal TotalCarrinho { get; set; }
	public string Mensagem { get; set; }
}

Podemos observar que esta View Model possui um IEnumerable de Produtos para uma lista de produtos e mais os dados de valor e mensagem que irão ser exibidos na View.
Não é um tipo de classe especial, é uma classe como qualquer outra Model, porém escrita especificamente para atender a uma View.

Confira o código da Controller de carrinho de compras.

public class CarrinhoComprasController : Controller
{
    public ActionResult Index()
    {

        // Criando uma lista de produtos fake para exibição na View
        var produtos = new List<Produto>();
        for (int i = 0; i < 10; i++)
	    {
            produtos.Add(new Produto
                            { Nome = "Produto " + i, Valor = 1.13M * i }
                        );
        }

        // Populando a model para exibição na View
        var model = new CarrinhoComprasViewModel
	    {
            Produtos = produtos,
            TotalCarrinho = produtos.Sum(p => p.Valor),
            Mensagem = "Obrigado por comprar conosco!"
        };

        return View(model);
    }

}

E por fim a View de carrinho de compras

@model MeuExemploMVC.Models.CarrinhoComprasViewModel

@{
    ViewBag.Title = "Carrinho de Compras";
}

<h2>@Model.Mensagem
</h2>
<fieldset>
    <legend>Carrinho de Compras</legend>

    <table>
        <caption>Produtos no Carrinho</caption>
        <thead>
        <tr>
            <th>Produto</th>
            <th>Valor</th>
        </tr>
        </thead>
        <tbody>
        @foreach (var produto in Model.Produtos) {
            <tr>
                <td>@produto.Nome</td>
                <td>@produto.Valor</td>
            </tr>
        }
        </tbody>
        <tfoot>
            <tr>
                <td><strong>Total</strong></td>
                <td>@Model.TotalCarrinho</td>
            </tr>
        </tfoot>
    </table>

</fieldset>

O pattern de View Model está aplicado e não será mais necessário modificar a Model de Produto para adequar a View.

O arquivo físico de uma View Model pode estar em diferentes lugares, sendo:

  • Em uma pasta chamada ViewModels na estrutura raiz do projeto MVC (aplicações pequenas)
  • Uma *.dll referenciada no projeto MVC (aplicações de qualquer tamanho)
  • Em projetos separados (como uma camada de serviços) para gerar dados específicos (aplicações grandes)

Utilizando AutoMapper para realizar o mapeamento de uma Model e suas variantes

Uma outra forma de utilizar View Models seria criando um mapeamento entre a Model entidade de domínio e a View Model que será exibida na View.

Os autores do livro ASP.Net MVC 4 in Action defendem fortemente a utilização de mapeamento entre as Models e suas possíveis variantes.

Com base no exemplo acima, a classe Produto poderia ter uma variante chamada ProdutoViewModel, qual possuiria os mesmos atributos de Produto entre outros mais.

O mapeamento entre essas duas Models seria feito através da ferramenta AutoMapper.
Este é um processo mais complexo e será abordado em meu post exclusivo sobre utilização do AutoMapper.

Benefícios de usar uma View Model

  • Não precisar alterar uma classe Model para atender as necessidades de uma View.
  • Poder agrupar informações de uma ou mais Models em uma única classe, poupando a necessidade de realizar N consultas.
  • Um dado não contido em uma Model de domínio pode ser facilmente transportado através de uma View Model.
  • Mudanças são muito mais fáceis de se realizar e sem afetar a Model do domínio.
  • Não é necessário “poluir” as Models de domínio com DataAnnotations de validação de formulário, pois estas podem estar contidas diretamente na View Model.

Resumo

O uso de View Models é muito recomendado e irá ajudar a organizar e gerenciar os dados a serem transportados e exibidos, proporcionando flexibilidade para montar conjuntos de dados compatíveis com as necessidades da View.

No MVC existe o conceito de separação de responsabilidades onde “M” (Model) é considerada a menos importante, pois nem sempre a Model estará presente no projeto MVC e sim numa camada de domínio que irá prover estas classes. A Model do MVC está voltada ao uso na View, portanto algumas técnicas são necessárias para separar e mapear Models de entidades de domínio para Models do projeto MVC.

Referências

Aguardem o próximo artigo complementar sobre AutoMapper 😉
Dúvidas e feedbacks são sempre muito bem vindos, utilize os comentários abaixo.

ASP.Net MVC – Autenticando usuário através da conta do Facebook

A utilização de contas de redes sociais para autenticação em outras aplicações já é uma realidade, aprenda como autenticar um usuário utilizando a conta do Facebook em sua aplicação ASP.Net MVC e faça parte desta nova tendência.

ASP.Net MVC + Facebook

O ASP.Net MVC em conjunto com o Visual Studio proporciona uma enorme facilidade em executar esta integração, um projeto no template Internet Application por exemplo já vem praticamente pronto para realizar essa integração com as seguintes contas:

  • Facebook
  • Twitter
  • Microsoft
  • Google

Sua aplicação ASP.Net MVC pode trabalhar com estes quatro modelos simultaneamente sem problema algum, o esquema de membership do ASP.Net proporciona o armazenamento e identificação de cada tipo de login e sua rede social de origem.

Neste artigo gravei um vídeo seguindo passo a passo como integrar uma aplicação ASP.Net MVC com o Facebook, porém este processo é muito similar a integração com as demais redes sociais disponíveis.

Neste vídeo não foi necessário utilizar nenhum plugin externo, porém faço menção ao Facebook SDK for .NET que é um SDK para trabalhar com recursos avançados de integração com o Facebook, como por exemplo postar informações na timeline e interagir com a lista de amigos.

A partir do momento em que o usuário está autenticado numa aplicação ASP.Net MVC utilizando a conta do Facebook o Facebook SDK complementa as demais funcionalidades possíveis para uma interatividade completa.

Obtenha o Facebook SDK for .NET no site:
http://facebooksdk.net/

Ou instale diretamente via NuGet

PM> Install-Package Facebook

Em um próximo vídeo exibirei como utilizar esse SDK e realizar integrações no Facebook além do login.

Espero que aproveite o vídeo e deixe seu feedback ou dúvidas aqui nos comentários.

ASP.Net MVC – Propriedade com o atributo DataType.Date não exibe valor na View

Propriedade na Model decorada com o DataAnnotation [DataType(DataType.Date)] ao ser criada na View através do @Html.EditorFor não exibe os dados gravados no banco.

Essa é uma dica rápida mas que pode lhe poupar algum tempo, o cenário abordado resulta em um problema muito comum de ocorrer e será detalhado aqui como solucionar.

Em uma classe Model possuímos uma propriedade que representa uma data, estamos utilizando DataAnnotation para definir alguns comportamentos.

public class MeuModelo
{
    [Display(Name = "Data de Retorno")]
    [DataType(DataType.Date, ErrorMessage="Data em formato inválido")]
    public DateTime? DataRetorno { get; set; }
}

Note que está sendo utilizado o atributo [DataType(DataType.Date)] para definir a forma que este dado será validado na View.

Por tratar-se de uma solução ASP.Net MVC, muito provavelmente será utilizado o HtmlHelper (Razor) para facilitar a criação do controle na View.

    <div>
        @Html.LabelFor(model => model.DataRetorno)
        @Html.EditorFor(model => model.DataRetorno)
        @Html.ValidationMessageFor(model => model.DataRetorno)
    </div>

Ao chamar a View teremos uma surpresa, o campo além de estar criado, tornou-se um DatePicker, fantástico não?

ASP.Net MVC DatePicker

Esse é um recurso do ASP.Net MVC para browsers que suportam HTML5, logo se o seu browser possui esse suporte você terá acesso a este recurso.

Até neste momento tudo está funcionando perfeitamente até que chega o momento em que este campo data irá exibir um dado já gravado (ex banco de dados).
A data não aparece, o campo continua tendo o mesmo aspecto, como se não tivesse sido preenchido.

Você debuga o código, valida o preenchimento da model e o dado está la populado. Que problema é esse? É neste momento que entra a dica:

Para exibir corretamente a data, o valor deve ser formatado como AAAA-MM-DD

[RFC 3339] definida pelo W3C diz o seguinte:

“A valid full-date as defined in [RFC 3339], with the additional qualification that the year component is four or more digits representing a number greater than 0.”

Ou seja, é necessário formatar este campo data para adequar o seu funcionamento.
Caso a página estiver sendo exibida em um browser sem suporte a HTML5 o problema não ocorrerá, porém de qualquer forma necessita ser tratado, afinal todos os browsers atuais possuem esse suporte.

Para corrigir o problema será usado o atributo DisplayFormat, uma classe do DataAnnotations que especifica como que um dado dinamicamente criado deve ser exibido.

public class MeuModelo
{
    [Display(Name = "Data de Retorno")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
    [DataType(DataType.Date, ErrorMessage="Data em formato inválido")]
    public DateTime? DataRetorno { get; set; }
}

O formato da composição da string deve ser exatamente como está exibido no exemplo.
Ao testar a View percebemos o resultado, funcionou e agora está exibindo o dado gravado.

ASP.Net MVC DatePicker

Caso você tenha problema com o formato da exibição da data, talvez seja necessário utilizar os scripts jQuery Globalize para adequação do formato para a cultura do idioma da página.

Espero que essa dica possa ajudar, qualquer dúvida poste nos comentários abaixo 😉

MVC Summit 2013

O MVC Summit é um evento anual, gratuito e online, 14 palestras sobre ASP.NET e Web foram transmitidas ao vivo e estão disponíveis para exibição no Youtube.

MVC Summit

No último sábado (27/07) ocorreu o MVC Summit 2013, um evento anual e online, organizado pelo André Baltieri e Victor Cavalcante.

Neste ano o formato do evento foi alterado, o Google Hangouts foi utilizado para transmissão online. O MVC Summit 2013 contou com 2 trilhas (MVC e Web) onde alguns dos grandes nomes da comunidade palestraram sobre ASP.Net e Web Standards.

A minha palestra foi sobre ASP.Net SignalR, para ter acesso as minhas demos e slides acesse o conteúdo deste outro artigo: Palestra sobre ASP.Net SignalR + Demos + Vídeo

As palestras foram transmitidas ao vivo mas foram todas gravadas pelo Youtube e estão disponíveis abaixo:

Trilha MVC

Parte 1

Parte 2

Parte 3

Trilha Web

Parte 1

Parte 2

Acesse o site do MVC Summit 2013
http://www.mvcsummit.com.br

Meus agradecimentos aos organizadores e todos os espectadores que assistiram, interagiram e deixaram seu feedback. Até a próxima edição.

ASP.Net Web API 2 – O que há de novo?

O ASP.Net Web API 2 foi anunciado no Microsoft Build Developer Conference 2013 (25/06 -28/06), onde foram também anunciadas ótimas novidades para o ASP.Net em geral em conjunto com o novo Visual Studio 2013.

ASP.Net Web API 2

Para ter um maior entendimento sobre ASP.Net Web API recomendo começar pela leitura do artigo ASP.Net Web API – Meu primeiro serviço REST.

Novidades no ASP.Net Web API 2

Attribute Routing

O ASP.Net Web API agora suporta atributos de roteamento (Attribute Routing). Com os atributos de roteamento é possível especificar as rotas Web API por anotação nas Actions e Controllers como no exemplo a seguir.

[RoutePrefix("orders")]
public class OrdersController : ApiController
{
    [HttpGet("{id}")]
    public Order Get(int id) { }

    [HttpPost("{id}/approve")]
    public Order Approve(int id) { }
}

O Attribute Routing possui uma sintaxe conveniênte para especificar parâmetros opcionais (people/{name?}), valores default (people/{name=Dan}) e constraints de rota (people/{name:alpha}).

Usando o Attribute Routing, é possível de forma fácil definir uma hierarquia de recursos através de um única API controller.

public class MoviesController : ApiController
{
    [HttpGet("movies")]
    public IEnumerable Get() { }

    [HttpGet("actors/{actorId}/movies")]
    public IEnumerable GetByActor(int actorId) { }

    [HttpGet("directors/{directorId}/movies")]
    public IEnumerable GetByDirector(int directorId) { }
}

O Attribute Routing é uma feature muito útil e proporciona um controle muito mais granular, tornando o desenvolvimento mais rápido e prático.

Para saber mais:

Melhorias com OData: $select, $expand, $batch, $value e extensibilidade.

O ASP.Net Web API OData agora tem suporte completo para $select, $expand e $value.
É possível usar $batch para requests em lotes e processamento de changsets.

Melhorias de extensibilidade nos formatadores OData permitem adicionar Atom entry Metadata, suporte a Named Stream e Media Link, adicionar Instance Annotations e customização de Link Generation.

Para saber mais:

Request Batching

Request Batching permite combinar várias operações em um único HTTP POST, assim reduzindo o tráfego de rede e fornecendo uma UI mais leve.

O ASP.NET Web API passa a suportar requisições em lote utilizando o endpoint $batch apresentado nas melhorias com OData.

Para ativar o Request Batching basta adicionar uma rota com um batching handler na configuração do Web API.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpBatchRoute(
        routeName: "WebApiBatch",
        routeTemplate: "api/batch",
        batchHandler: new DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer));
    }
}

Para saber mais:

Portable ASP.NET Web API Client

Agora é possível utilizar o client do ASP.NET Web API em bibliotecas de classes portáveis que irão trabalhar com aplicativos Windows Store e Windows Phone 8.
Além disso é possível também criar o próprio formatador que será compartilhado entre cliente e servidor.

Isto torna muito mais fácil a escrita de clients .Net que interagem com serviços HTTP RESTful.

Para saber mais:

Melhorias na Testabilidade

Testes de unidade em API Controllers ficaram muito mais fáceis de serem escritos, basta instanciar a API Controller e então chamar a Action Method que deseja testar. É possível de forma muito fácil fazer o mock da classe UrlHelper nos casos em que o Action Method realiza a geração de link.

IHttpActionResult

Na primeira versão do ASP.Net Web API existiam duas maneiras de criar um response de uma API Action, retornar a instância de um objeto conhecido e deixar a Web API convertê-lo em um HttpResponseMessage ou retornar um HttpResponseMessage padrão.

No ASP.Net Web API 2 existe uma terceira opção a IHttpActionResult, muito simples e extremamente poderosa, é efetivamente uma factory para HttpResponseMessage e pela implementação de sua interface é possível fornecer instruções de como o novo response deve ser construído.

Para saber mais:

CORS

O ASP.Net Web API 2 agora possui suporte total a CORS.

A segurança presente nos browsers impedem uma página web de fazer requisições AJAX em outro domínio, essa restrição é chamada de Same-origin policy, porém algumas vezes isso pode ser necessário.

Cross Origin Resource Sharing (CORS) é um padrão W3C que permite que um servidor relaxe em relação a Same-origin policy, usando CORS um servidor pode permitir explicitamente algumas solicitações e rejeitar outras.

Para saber mais:

Authentication Filters

Authentication Filters são um novo tipo de filtro no ASP.NET Web API, são executados antes dos authorization filters no pipeline do Web API e permitem que seja especificada a lógica de autenticação, podendo “per-action”, “per-controller” ou globalmente para todos os controllers.

Authentication Filters processam credenciais durante um request e também podem adicionar “challenges” de autenticação em resposta à solicitações não autorizadas.

Filter Overrides

Agora é possível sobrescrever os filtros que se aplicam a uma determinada action ou controller especificando um conjunto de tipos de filtros que não devem ser executados em um determinado escopo (action ou controller).

Isso permite que sejam configurados os filtros que se aplicam globalmente, porém em seguida excluir determinados filtros globais da aplicação em actions ou controllers específicos.

Suporte e integração com OWIN

O ASP.Net Web API 2 agora suporta totalmente OWIN e poderá rodar em qualquer host que também possua suporte ao OWIN.

Para saber mais:

External Authentication Services

Agora os serviços ASP.Net Web API poderão integrar-se com serviços de autenticação externos como OAuth e OpenID e serviços de autenticação de redes sociais como Microsoft, Twitter, Facebook e Google.

Para saber mais:

Resumo

O ASP.Net Web API 2 possui diversas novidades em relação a primeira versão, todas elas foram planejadas para proporcionar uma maior abrangência na implementação de integrações, extensibilidade com outras tecnologias, segurança no tratamento das requisições e facilidade no desenvolvimento.

Quem já usou o ASP.Net Web API com certeza identificou nessa nova versão grandes e potenciais melhorias que o torna a melhor opção para criação de serviços HTTP REST.

Referências

Gostou deste artigo? Compartilhe e deixe seu comentário abaixo 😉

e-Book 25 dicas de performance para ASP.NET

Confira como ganhar mais performance em suas aplicações ASP.Net com 25 dicas práticas disponíveis gratuitamente neste e-Book, muitas delas são simples de implementar e podem trazer muitos resultados positivos.

25 dicas de performance em ASP.Net

A crescente adoção de ASP.Net MVC 4 e Web API entre outras tecnologias significam novas oportunidades para melhorias de desempenho e funcionalidades.

Este e-Book foi escrito por influentes membros da comunidade ASP.Net e utiliza variadas tecnologias e funcionalidades para resolver problemas conhecidos, é uma leitura fácil e dinâmica, algumas das dicas dão vontade de parar de ler na hora para ir correndo implementar.

Confira alguns dos termos e tecnologias em destaque nestas 25 dicas:

  • ASP.Net MVC
  • ASP.Net Web API
  • LINQ
  • Entity Framework
  • RavenDB
  • C# Async / Await
  • Javascript
  • JSON
  • OutputCache

Download

Referência

Conseguiu ter uma boa experiência com estas dicas? Recomenda a leitura?
Participe contribuindo com sua opinião nos comentários abaixo.

Palestra sobre ASP.Net SignalR + Demos + Vídeo

Palestra sobre ASP.Net SignalR ministrada no Visual Studio Summit 2013.

ASP.Net SignalR

Desde que comecei a estudar ASP.Net SignalR me interessei muito e se tornou um dos meus assuntos favoritos, acompanhe aqui como foi minha palestra:

Vídeo da Palestra

Eu ainda não sou o bom palestrante que desejo ser, mas um dia chego lá 🙂

Slides

Demos (compatíveis com VS 2012)

*Jogo da velha original foi baixado aqui. Fiz melhorias, correções e complementos para demonstração.

Quer conhecer mais sobre ASP.Net SignalR? Leia o meu artigo aqui.

O Visual Studio Summit é um dos maiores eventos sobre desenvolvimento na plataforma Microsoft, assista todas palestras da edição 2013 aqui.

Deixe seu feedback logo abaixo 🙂
Abraços!

ASP.Net MVC – ViewData, ViewBag e TempData

ASP.Net MVC – ViewData, ViewBag e TempData entenda as diferenças.

Quando usar ViewData, ViewBag e TempData? Essa é uma das primeiras perguntas que qualquer desenvolvedor faz quando inicia nos aprendizados do ASP.Net MVC.

UPDATE – 13/06 – Adicionando detalhes/correções fornecidos pelo @vcavalcante

Vamos basear nossa explicação conforme a ilustração

ViewData, ViewBag, TempData

Similaridades entre ViewData e ViewBag

ViewData e ViewBag são similares nas seguintes características:

  • São utilizadas para persistir dados entre a Controller e a View correspondente.
  • A duração “tempo de vida” é apenas entre o envio através da Controller e a exibição na View, depois disso tornam-se nulas novamente.
  • No caso de um redirect se tornam nulas.

Diferenças entre ViewData e ViewBag

ViewData ViewBag
É um dicionário de objetos derivado de ViewDataDictionary e é acessível utilizando strings como chaves. É uma propriedade dinâmica baseada na funcionalidade “dynamic” do C# 4.0
Requer typecasting (conversão) quando associada a tipos complexos. Não necessida de conversão para tipos complexos.

Exemplos de aplicação

Controller

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // Meu dado de tipo complexo
        var func = new Funcionario
                        {
                            Nome = "Eduardo Pires",
                            Idade = 31
                        };

        // Propriedades "Dinâmicas"
        ViewBag.Funcionario = func;

        // Modo tradicional
        ViewData["Funcionario"] = func;

        return View();
    }
}

View

@model ProjetoModelo.Models.Funcionario;

@{
    ViewBag.Title = "Exemplo ViewData ViewBag";

    // Necessita de TypeCasting
    var viewDataVariavel = ViewData["Funcionario"] as Funcionario;

    // Não necessita de TypeCasting
    var viewBagVariavel = ViewBag.Funcionario;
}

Resumindo, ViewData e ViewBag possuem a mesma proposta, porém o ViewBag está disponível a partir do ASP.Net MVC 3, enquanto o ViewData existe desde a primeira versão.

OBS: O ViewData é um wrapper, uma implementação do ViewBag, pois utiliza o ViewBag internamente, portanto:

// Criar o ViewBag:
ViewBag.Teste = "Eduardo";

// É o mesmo que criar um ViewData["Teste"],
// pois o ViewData é utilizado internamente. Se chamarmos:

var teste = ViewData["Teste"]; // Teremos teste = "Eduardo";

Por este motivo ViewData é mais rápido que o ViewBag, porém essa diferença de velocidade é mínima, não é necessário deixar de usar o ViewBag por este motivo.

Eu preferencialmente sempre utilizo ViewBag

TempData

  • TempData assemelha-se mais a uma sessão de servidor, porém de curta duração.
  • Possui um tempo de vida maior que o ViewBag e ViewData, o TempData perdura desde sua criação até que seja chamado, ou seja, quando houver um request da informação do TempData, ele se tornará nulo novamente.
  • Uma informação em TempData criada em um Controller persiste após um redirect entre actions (apenas um) e pode ser exibido em sequência em uma View (muito usado em tratamento de erros).
  • Caso não seja chamado o TempData pode manter o estado de seus dados até que a sessão do usuário se encerre.
  • É utilizado para compartilhar informações entre Controllers.
  • O TempData salva suas informações no SessionState do servidor.
  • Após a leitura os dados do TempData são marcados para deleção, ou seja, no final do request todos os dados marcados serão deletados.
  • É um benefício quando necessário transmitir um volume de informações entre as Controllers sem se preocupar em zerar os valores, pois o TempData automaticamente faz isso.

Exemplo de aplicação

Controller

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult CriarFuncionario(Candidato cd)
    {
        // Meu dado de tipo complexo
        var func = new Funcionario
                        {
                            Nome = cd.Nome,
                            Idade = cd.Idade
                        };

        // Pertistir dados até o próximo request.
        TempData["Funcionario"] = func;

        // Redirect entre Controllers
        return RedirectToAction("CriarBeneficiosFuncionario");
    }

    [HttpGet]
    public ActionResult CriarBeneficiosFuncionario()
    {
        // Validando se está vazio
        if (TempData["Funcionario"] != null)
        {
            // Necessário TypeCasting para tipos complexos.
            var func = TempData["Funcionario"] as Funcionario;
        }

        return View();
    }
}

Neste exemplo pudermos entender que o propósito do TempData é compartilhar dados entre Controllers, portanto sua duração persiste até que a informação seja lida.
Outro detalhe é sempre checar se o TempData não está nulo.

Caso você queira manter o dado de um TempData mesmo após a leitura, basta chamar o método Keep(), assim o dado será persistido novamente até a próxima requisição.

// Mantendo o dado do TempData até a próxima leitura (requisição).
TempData.Keep("Funcionario");

// Removendo o dado do TempData desta e da próxima requisição.
TempData.Remove("Funcionario");

Recomenda-se utilizar sempre ViewBag e ViewData para transferência de dados entre Controller e View. O TempData em Views é recomendado no caso de um dado necessitar ser redirecionado entre Actions e posteriormente ser exibido numa View (ViewBag e ViewData são anulados em redirects).
Um caso comum dessa aplicação é no tratamento de erros, veja aqui um exemplo.

Espero ter esclarecido as diferenças e características de ViewData, ViewBag e TempData. Caso tenha alguma dúvida ou queira comentar algo, deixe seu recado logo abaixo 😉

Referências

Vou palestrar no evento de 10 anos do Codificando.Net

Olá Pessoal,

O Codificando.Net é uma das maiores comunidades de desenvolvedores de software e está comemorando seus 10 anos com um evento presencial.

O evento terá diversas apresentações sobre Desenvolvimento Web, SQL, Business Intelligence e Cloud Computing.

O tema da minha palestra será Comunicação em tempo real usando ASP.NET SignalR

Esta é mais uma ótima oportunidade de aprender, conhecer as novidades, fazer contatos e trocar conhecimentos com a comunidade técnica.

Informações

O dinheiro arrecadado com as inscrições do evento, cobrirão o coffee-break e a compra de alimentos não perecíveis para doação à instituição de caridade (à definir).

Espero você lá!

 

ASP.NET SignalR – Introdução e Utilização

O ASP.NET SignalR é uma biblioteca open-source que facilita a implementação de comunicação em tempo real, atualizações/notificações de forma assíncrona em uma aplicação.

Foi desenvolvido por dois funcionários da Microsoft – Damian Edwards e David Fowler, todo o código fonte do projeto está disponível no GitHub

Há um certo tempo foi incorporado pela plataforma ASP.Net, sendo:

ASP.Net SignalR

Funciona através de uma biblioteca Server Side (ASP.Net) e uma Client Side (Javascript), é suportado em aplicações do tipo Silverlight, Windows Phone 7 e 8 e WinRT. Veja a lista completa de plataformas suportadas aqui.

Quem já precisou desenvolver uma aplicação real-time conhece as dificuldades de manter um certo volume de conexões do servidor, manipular a maneira que o servidor trata as requisições, garantir que o client esteja exibindo as informações no tempo certo e enfim.

Existem alguns meios de implementar uma comunicação em tempo real (Long Polling, WebSockets, Node.js) todas essas técnicas/tecnologias possuem sua complexidade ou limitação técnica, o SignalR propõe a facilitar a implementação da comunicação real-time em sua aplicação.

O que é uma aplicação real-time?

É uma aplicação onde a informação chega em tempo real, imagine um chat ou um ticker de cotação da bolsa de valores, essas informações estão sendo distribuídas em tempo real para todos os clientes consumidores da aplicação.
Para se desenvolver uma aplicação em tempo real é necessário que o servidor seja capaz de sensibilizar todos os clientes conectados assim que uma informação chegar.

Como funciona?

O ASP.Net SignalR é uma abstração de uma conexão, ele trabalha por baixo dos panos definindo o melhor tipo de transporte em dois níveis diferentes de abstração o que ocasiona uma impressão de uma conexão persistente.

ASP.Net SignalR

Transportes

Um dos grandes pontos do ASP.Net SignalR é sua capacidade de gerenciar a escolha do tipo de transporte a ser utilizado.

Como mostra a figura existem quatro tipos de transportes disponíveis:

  1. WebSockets
  2. Long Polling
  3. Server Sent Events
  4. Forever Frame

Lendo a documentação do ASP.Net SignalR iremos entender que fica a cargo dele encontrar o transporte mais eficaz entre um server/client, dando sempre preferência por WebSockets quando disponível e caso não esteja disponível parte para Long Polling e os demais em sequência.

WebSocket é uma tecnologia que permite a comunicação bidirecional por canais full-dulplex sobre um único soquete Transmission Control Protocol (TCP). Ela foi projetada para ser executada em navegadores e servidores web que suportem o HTML5, mas pode ser usado por qualquer cliente ou servidor de aplicativos. A API WebSocket está sendo padronizada pelo W3C e o protocolo WebSocket está sendo padronizado pelo IETF.

Sendo assim apesar de termos tipos de transportes variantes o código fonte é sempre o mesmo, a responsabilidade de escolher o tipo de transporte fica por conta do SignalR, porém existe disponível uma maneira de definir o uso de um transporte específico.

Comunicação com PersistentConnection e Hubs

O ASP.Net SignalR oferece dois níveis de abstração de comunicação entre clientes e servidores, sendo o Hubs de alto nível e PersistentConnection de baixo nível.

PersistentConnection representa um endpoint de comunicação com um único destinatário, agrupamentos ou mensagens de broadcast.
É necessário a configuração de uma rota customizada dentro do arquivo Global.asax.

A API de conexão (representada em código .Net pela classe PersistentConnection) dá ao desenvolvedor acesso direto a comunicação de baixo nível que o SignalR expõe, similar a forma de trabalhar com Sockets. O modelo de comunicação PersistentConnection será familiar para os desenvolvedores que usam API’s baseadas em conexão como o Windows Communcation Foundation – WCF.

Hubs é um pipeline de mais alto nível construído sobre a API PersistentConnection  e que permite que o cliente e servidor chamem métodos entre si diretamente.
O SignalR lida com o envio através dos limites da máquina, permitindo que o cliente chame os métodos no servidor tão facilmente como métodos locais e vice-versa.
Se o seu aplicativo usa diferentes tipos de mensagens é recomendável que você use a classe Hub, de modo que você possa chamar métodos no client em vez de enviar uma mensagem explícita que precisa ser recebida, interpretada e posta em prática. Usando o modelo de comunicação Hubs será familiar para os desenvolvedores que usam API’s de invocação remota como. NET Remoting.

A escolha de um modelo de comunicação

A maioria dos aplicativos deve usar o modelo Hubs.
PersistentConnections podem ser utilizados nas seguintes circunstâncias:

  • O formato da mensagem enviada necessita de ser controlado.
  • O desenvolvedor prefere trabalhar com um modelo de envio de mensagens ao invés de um modelo de invocação remota.
  • Um aplicativo existente que usa um modelo de mensagem está sendo portado para usar SignalR.

Como começar?

É necessário o Visual Studio 2010 SP1 ou o Visual Studio 2012

  • Inicie um projeto ASP.Net MVC
  • Instale o ASP.Net SignalR através do Nuget:
Install-Package Microsoft.AspNet.SignalR
  • Adicione um Controller vazio
public class ChatController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
  • Crie uma View
@{
    ViewBag.Title = "Chat Básico";
}
<label for="apelido" >Seu Apelido:</label><input type="text" name="apelido" id="apelido" /><br />
<label for="mensagem" >Mensagem:</label><input type="text" name="mensagem" id="mensagem" maxlength="100" />
<div id="chatWindow" style="width: 100%; height: 300px; overflow: scroll; border: 1px solid grey"></div>

<!-- Referenciando os scripts adicionados ao Bundle -->
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/SignalR")

<!-- Referencia para o script de Hub criado automaticamente -->
<script src="/signalr/hubs" type="text/javascript"></script>

<script type="text/javascript">
    $(function () {
        // Declarando um proxy de referencia ao Hub
        var chatHub = $.connection.chat;

        // Criando a função que será chamada pelo Hub para distribuir as mensagens aos clientes.
        // Por convenção as chamadas aos métodos são feitas em "camelCase"
        chatHub.transmitirMensagem = function (apelido, msg) {

            // Area do chat
            var chatWin = $("#chatWindow");

            // Publicando a mensagem no chat
            chatWin.html(chatWin.html() + "<b>" + apelido + "</b>: " + msg + "<br />");
        };

        // Iniciando a conexão com o Hub
        $.connection.hub.start();

        // Validando o botão enter
        $(document).keypress(function (e) {
            if (e.which == 13) {

                // Chamando o método de transmissão de mensagem no Hub
                chatHub.enviarMensagem($("#apelido").val(), $("#mensagem").val());

                // Limpando o texto da mensagem.
                $("#mensagem").val("");
            }
        });
    });
</script>
  • Crie um Hub
public class Chat : Hub
{
    public void EnviarMensagem(string apelido, string mensagem)
    {
        Clients.TransmitirMensagem(apelido, mensagem);
    }
 }

Este exemplo está disponível para download aqui.

Ao executar o projeto abra uma segunda instância de um browser (experimente browsers diferentes) e teste a conversação do chat.

ASP.Net SignalR

É incrivelmente fácil, não é mesmo?
O client chama métodos no Hub (server) como se fossem métodos locais e os métodos no server chamam métodos no client como se fossem métodos no servidor.

Quero conhecer e aprender mais!

Leia estes dois sites:

Assista este ótimo vídeo que foi gravado no TechEd 2012 por um dos desenvolvedores do  ASP.Net SignalR.

Leia este Free eBook do MVP JM Aguilar, eu já li e recomendo (inglês)

Mais exemplos para baixar:

Baixou o código fonte e teve alguma dúvida? Colocou a mão na massa e quer conhecer algum detalhe mais profundamente? Os desenvolvedores do ASP.Net SignalR respondem, eles ficam disponíveis neste chat, eu dei meu alô para eles e fui respondido:

ASP.Net SignalR

O exemplo do chat é o mais simples e clássico para usar na comunicação em tempo real, porém as possibilidades de utilização são inúmeras, adicione o ASP.Net SignalR em seu conhecimento técnico e faça proveito.

Este foi um post introdutório, falarei muito mais deste assunto em outros artigos, estou preparando uma aplicação especial para disponibilizar na comunidade utilizando ASP.Net SignalR e também tem minha palestra no Visual Studio Summit 2013 (será gravada e disponibilizada aqui).

Dê seu feedback e tire suas dúvidas nos comentários abaixo.
Gostou deste artigo? Compartilhe 😉

Referências