Integrando ASP.NET Core com ASP.NET MVC 5

Migrando para o ASP.NET Core? Não é necessário migrar todo o projeto de uma única vez, utilize migrações modulares e compartilhe o Cookie de autorização de usuários.

O ASP.NET Core está pronto e muitas demandas de migração de projetos ASP.NET 4.X para a nova plataforma irão surgir. Como planejar e executar esta migração?

ASP.NET Core & ASP.NET 4.X

Uma migração total pode ser complexa, afinal vai exigir a alocação de diversas pessoas e enquanto isto as duas aplicações precisarão receber futuras implementações. Alguns projetos são tão grandes que simplesmente não seriam migrados se esta fosse a única alternativa, seria impossível atender as duas demandas simultaneamente.

Por que não ter duas aplicações?

Não há motivos para uma migração total se sua aplicação já funciona bem. Portar parcialmente módulos da aplicação para um projeto ASP.NET Core é uma alternativa bem mais interessante e que vai exigir muito menos esforço.

Imagine que em sua aplicação o módulo de gestão de Produtos funciona no ASP.NET MVC 5 e o módulo de gestão de Clientes no ASP.NET Core, o usuário final mal poderá perceber a diferença!

Integração de dados entre duas aplicações.

Certo! Posso migrar parcialmente, mas como faço a integração entre os dados que estão em aplicações diferentes?

Uma aplicação que utiliza uma boa arquitetura e uma boa modelagem estratégica pode facilmente integrar diversas entidades através dos ORM’s. Se a aplicação possuir uma modelagem DDD cada Bounded Context resolve seus próprios problemas, migre um BC de cada vez! (está mais fácil do que você imagina).

Compartilhando o usuário entre duas aplicações

Este é o grande foco da abordagem que apresento, como realizar uma integração para uma aplicação ASP.NET Core compartilhar o mesmo usuário de uma aplicação ASP.NET MVC 5.

Disponibilizei um novo repositório no meu GitHub com o projeto AspNetInterop este projeto implementa exatamente este cenário onde duas aplicações ASP.NET Core 1.1 e ASP.NET MVC 5 compartilham o mesmo Usuário, Cookies, Claims e Token para o AntiForgery.

Para reproduzir este projeto você precisa utilizar alguns Nuget Packages

Utilize o mesmo Cookie entre as aplicações

Esta abordagem faz a utilização do ASP.NET Identity, mas é possível produzir o mesmo resultado utilizando somente as classes do Microsoft.Owin.Security.

O importante é setar o mesmo cookie entre as duas aplicações:

services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
    options.Cookies = new Microsoft.AspNetCore.Identity.IdentityCookieOptions
    {
        ApplicationCookie = new CookieAuthenticationOptions
        {
            AuthenticationScheme = "Cookie",
            LoginPath = new PathString("/Account/Login/"),
            AccessDeniedPath = new PathString("/Account/Forbidden/"),
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            CookieName = ".AspNet.SharedCookie"

            // If you have subdomains use this config:
            CookieDomain = "localhost"
        };
    })
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

É necessário que as aplicações rodem no mesmo nome de domínio, se você tiver sub-dominios para cada aplicação basta setar a raíz do domínio em CookieDomain.

Selecione um repositório para Data Protection

O exemplo está utilizando um diretório como repositório, mas o ASP.NET Core 1.1 já suporta Redis, Azure Blob Storage e Azure Key Vault.

No ASP.NET MVC 5 além de configurar o Identity para utilizar o mesmo cookie (verifique implementação no código fonte) é necessário configurar o AntiForgery para que o usuário consiga utilizar a mesma chave entre as aplicações, para isto é necessário esta configuração no Global.asax

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

O AntiForgery faz a validação baseada em claims e no cookie do usuário logado.

Migre o módulo de gestão de usuários primeiro

Para utilizar este recurso é importante que esteja utilizando o ASP.NET Core com o ASP.NET Identity 3.0, portanto eu sugiro que este seja o primeiro módulo a ser migrado. A implementação deste projeto compartilha a mesma base do ASP.NET Identity entre as aplicações.

Compartilhando Cookies entre ASP.NET Core e ASP.NET MVC 5

Esta implementação foi baseada no repositório idunno.CookieSharing do qual o Scott Hanselman faz parte dos integrantes. O projeto que disponibilizo no repositório AspNetInterop é uma melhoria da implementação original, no meu projeto as melhorias implementadas foram:

  • Utilização do ASP.NET Identity ao invés do Cookie Middleware
  • Implementação de controle de acesso com base em claims para o ASP.NET Core e ASP.NET MVC 5 (cada um possui uma implementação diferente devido a forma de autorizar usuários no ASP.NET Core ter mudado)
  • Compartilhamento do Cookie no AntiForgery
  • CRUD’s de entidades em cada aplicação
  • Navegação integrada para o usuário não notar a mudança

Este projeto não conta com divisão em camadas para implementar separação de responsabilidades de Dados, Negócios e etc, porém é muito simples de implementar, pois isto não gera impacto na implementação existente.

Código fonte


Caso esteja interessado em conhecer mais sobre ASP.NET, DDD, Padrões de Arquitetura como CQRS, Event Sourcing e boas práticas de desenvolvimento não deixe de conferir as ementas dos meus cursos:

Vamos continuar a troca de experiências, deixe seu comentário abaixo. Se gostou e concorda com o artigo, compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis.

Turbinando sua aplicação ASP.NET no IIS

Toda aplicação ASP.NET requer um processo de compilação em memória no servidor e isto leva um tempo perceptível por nossos usuários. Aprenda como evitar esse comportamento.

Turbinando sua aplicação ASP.NET no IIS

Na minha vida de consultor eu sempre ouço a mesma pergunta dos meus clientes:
Meu site fica lento na primeira chamada toda vez que faço um deploy ou quando o pool do IIS recicla naturalmente.

Antes de tudo é importante deixar claro que não tem como fugir do processo de reciclagem do pool do IIS, ele pode ocorrer naturalmente por N fatores ou agendado conforme sua configuração.

A demora natural na primeira chamada de uma aplicação ASP.NET é o processo do IIS compilando o assembly da sua aplicação e disponibilizando ele num cache, esse cache é usado nas próximas chamadas e assim sua aplicação volta a responder normalmente sem nenhuma demora aparente. Toda vez que o pool do IIS recicla a memória esse cache é perdido.

Nós não queremos que nossos usuários sejam obrigados a esperar este tempo de compilação que pode chegar em cerca de 30 segundos dependendo do tamanho da aplicação, é por isso que o IIS possui uma feature pouco utilizada chamada de
IIS Auto-Start ou Application Initialization

Para habilitar esse comportamento no seu IIS é necessário instalar o módulo de Application Initialization no seu servidor e seguir alguns passos na configuração do IIS.

*A mesma configuração pode ser feita através da edição dos arquivos de configuração no servidor. Eu prefiro fazer no IIS diretamente, você encontrará esta outra abordagem no link de referência no final do post.

O resultado é muito satisfatório, ao invés da aplicação demorar mais de 10 segundos para responder ela passa a demorar 1 ou 2 segundos.

Para abordar todos os passos necessários em detalhes eu gravei um vídeo de 16 minutos mostrando todo o processo de configuração.

* Assine meu canal no Youtube 🙂

Referências


Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações com uma arquitetura responsável utilizando DDD, TDD, BDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade conheça meus cursos:

Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis. ;)

Self-Hosting com SignalR e integração via ASP.NET MVC

O ASP.NET SignalR é um framework de comunicação em tempo real que pode ser utilizado para diversas funcionalidades, inclusive para integração de comunicação entre sistemas de diferentes plataformas.

Caso não conheça o ASP.NET SignalR aprenda em detalhes neste artigo e nesta palestra.

Integração de Comunicação em Tempo Real com ASP.NET SignalR

O ASP.NET SignalR vem sendo amplamente utilizado em diversos cenários de comunicação em tempo real. Muitas vezes a própria solução Web implementa os Hubs e gerencia o recebimento e distribuição de mensagens.

Existem outros cenários em que é necessário desacoplar o lado server do SignalR da aplicação Web. Muitas vezes a informação a ser distribuída pode vir de outros serviços, outras plataformas e etc. É possível utilizar SignalR nesses casos? Sim, é possível!

O SignalR é implementado seguindo a especificação do OWIN e pode trabalhar em uma aplicação Web ou no modo Self-Host em um Windows Service ou aplicação console.

Proponho um cenário hipotético: Existem N broadcasts sendo distribuídos de diversas aplicações independentes da Microsoft e é necessário que a comunicação seja transmitida em tempo real para outras plataformas (Web, Desktop, Mobile). É necessário utilizar uma solução única para atender esta demanda e com baixo esforço de desenvolvimento.

Este cenário é muito similar ao da imagem utilizada no início do artigo e segue o fluxo a seguir:

  1. O Windows Service implementa uma forma de receber a comunicação vinda das demais aplicações.
  2. Os Hubs do SignalR no Windows Service distribuem as informações recebidas à todos os clientes conectados.
  3. Os clientes conectados recebem a comunicação em tempo real e se necessário podem encaminhar novas informações para o Windows Service.
  4. O Windows Service recebe as informações de um cliente e redistribui para todos novamente (como num chat).

Desenvolvi a solução deste cenário utilizando um Windows Service gerando dados de tempo, dados aleatórios de valores e trabalhando com uma comunicação via chat.

Aplicação ASP.NET MVC recebendo em tempo real as informações do Windows Service no Chrome e no Edge.

A solução está publicada em meu GitHub

  • Para testes de desenvolvimento não é necessário instalar o serviço (Windows Service), basta setar os dois projetos para iniciarem juntos e realizar um Debug.
  • É possível implementar autenticação para transmitir a comunicação apenas para clientes com a devida permissão.
  • É possível implementar algum Retry Pattern como o Polly caso haja alguma falha na entrega da comunicação.

Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:


Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis. ;)

Ordene manualmente os seus scripts via Bundles

A feature Bundles e Minification foi introduzida a partir da versão do ASP.NET MVC 4 e trouxe bastante praticidade, porém precisamos de um ajuste manual para obter a ordenação exata dos scripts.

Utilizar os Bundles da forma tradicional pode ocasionar alguns problemas na execução de nossos scripts devido ao seu padrão de ordenação. Encontrar a solução para estes problemas pode tomar algumas horas de trabalho se não observarmos corretamente o comportamento dos Bundles.

Um exemplo simples:
Para utilizar a biblioteca de globalização de validações “jquery.validate.globalize.js” certamente precisaremos da biblioteca “jquery.validate.js” e “globalize.js”, pois são dependências para que a validação funcione de forma globalizada. Portanto para o browser poder executar os métodos de “jquery.validate.globalize.js” é necessário ter carregado previamente a bibliotecas que são dependências.

Utilizando os Bundles de forma tradicional teríamos uma configuração parecida com o exemplo a seguir.

// Adicionando jQuery
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
            "~/Scripts/jquery-{version}.js"));

// Adicionando Validação, e Globalização
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
            "~/Scripts/jquery.validate.js",
            "~/Scripts/globalize.js",
            "~/Scripts/jquery.validate.globalize.js"));

E por consequência o código HTML gerado para interpretação do browser não seria o esperado.

Bundles Uncaught ReferenceError

Uncaught ReferenceError: Globalize is not defined

Este problema ocorreu por que o Bundle não gerou os scripts na ordem em que foram declarados como no código acima, pois sua ordenação padrão não respeita a ordem da declaração. Logo a biblioteca “jquery.validate.globalize.js” não encontrou sua dependência e não executou suas funções.

Existem algumas formas de resolver este problema, minha recomendação é criar uma classe de ordenação que respeita a ordem em que as bibliotecas foram declaradas. Esta classe pode ser criada no próprio arquivo “BundleConfig.cs” para manter a simplicidade da implementação.

public class AsIsBundleOrderer : IBundleOrderer
{
    public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}

E a forma de declaração do Bundle precisa ser modificada para fazer uso desta nova ordenação.

// Adicionando jQuery
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
            "~/Scripts/jquery-{version}.js"));

// Adicionando Validação, e Globalização
// Utilizando ordenação manual
var valBundle = new ScriptBundle("~/bundles/jqueryval").Include(
    "~/Scripts/jquery.validate.js",
    "~/Scripts/globalize.js",
    "~/Scripts/jquery.validate.globalize.js");

valBundle.Orderer = new AsIsBundleOrderer();

bundles.Add(valBundle);

Utilizamos algumas linhas a mais, porém garantimos a ordenação da forma que o browser precisa para poder executar tudo corretamente. O resultado é como o esperado.

Bundles Order Ok

Como podemos conferir é muito importante estar atento a este comportamento dos Bundles para evitar possíveis problemas e por consequência perder um tempo precioso de trabalho.

* Esta abordagem vale também para os StyleBundles que trabalham com CSS.

** Caso esteja trabalhando com o recurso de Minification este comportamento pode ocorrer ou não dependendo do cenário.


Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:

Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis. ;)

Desacoplando o ASP.NET Identity do MVC e Domínio

O ASP.NET Identity é uma ótima solução para a gestão dos usuários em sua aplicação, porém seu design é diretamente acoplado ao ASP.NET MVC e também devemos evitar de utilizar suas referências no domínio da aplicação.

Desacoplando o ASP.NET Identity. Finalmente após muitos pedidos eu consegui colocar a mão na massa e desenvolver um projeto modelo para ser usado como referência.

Desacoplando o ASP.NET Identity do MVC e Domínio

Como sabemos o ASP.NET Identity depende diretamente do EF (ou outros), Owin e System.Web, logo todas as implementações do ASP.NET Identity ficam de alguma forma acopladas em nossa camada de apresentação. Quando possuímos uma aplicação onde o usuário é uma peça importante no negócio existe a necessidade de representá-lo na camada de domínio, porém é altamente recomendado que a camada de domínio não conheça tecnologias terceiras (Identity, EF, outros).

Como resolver esse problema?

Foi após alguns estudos que cheguei no modelo que considero ser a “melhor abstração possível”, pois para o ASP.NET Identity funcionar na camada de apresentação é obrigatório levar algumas dependências, porém desde que esteja isolado em outra camada já conseguiremos ótimas boas vantagens.

Aviso: Caso você não conheça o ASP.NET Identity, DDD e Injeção de dependência sugiro que comece pelos tutoriais:

Neste tutorial você encontrará as seguintes tecnologias utilizadas

  • ASP.NET MVC 5
  • ASP.NET Identity 2
  • Entity Framework 6
  • Fluent API
  • Injeção de Dependência com Simple Injector
  • Owin
  • RestSharp para implementação do Twilio API (SMS)

Existem dois grandes objetivos nesta proposta, o primeiro objetivo é a reutilização, pois com um uma única solução (camada) de gestão de usuários é possível atender N aplicações, facilitando o gerenciamento e manutenção.

O segundo objetivo é permitir que a camada de domínio represente o usuário de forma abstraída, logo não existe referência direta do IdentityUser no domínio, porém é possível consultar os dados de usuário e incluir / modificar as informações salvas.

O primeiro passo é abstrair tudo, mover as dependências do Identity para uma camada isolada, depois injetar no MVC os objetos necessários, para essa implementação eu utilizei o Simple Injector, que como o próprio nome diz, é bem simples, rápido e atendeu bem a necessidade.

Com o Identity isolado e injetado devidamente na camada de apresentação (MVC) basta criar uma camada de acesso a dados que irá fornecer meios do domínio consumir dados do usuário de forma abstraída. A grande sacada está no uso correto do Fluent API e claro muita injeção de dependência.

A solução desde modelo não visa atender completamente a filosofia do DDD, pois procurei simplificar o bastante para deixar simples de modificar, por exemplo adicionando uma camada de Application. Portanto quem utilizar esta arquitetura deve estar ciente que algumas coisas a mais ainda precisam ser feitas.

Gostaria de ressaltar também que o template de projeto ASP.NET MVC que o Visual Studio fornece possui vários problemas de design de código. As controllers de Account e Manage do usuário precisaram ser parcialmente re-escritas para atender a injeção do Identity, problemas como mais de um construtor público e utilização do pattern (ou anti pattern?) Service Locator foram encontrados e retirados.

Para quem quiser acompanhar em detalhes técnicos toda a implementação dessa solução eu preparei o vídeo a seguir.

* Assine meu canal no Youtube 🙂

O código fonte desta solução está disponível no GitHub, caso queira propor alguma melhoria faça um Pull Request, será muito bem recebido.


Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:

Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis. ;)

Customizando Nomes de Tabelas e Campos no ASP.NET Identity

O ASP.NET Identity possui um padrão de nomenclatura para suas tabelas e campos, muitas vezes é necessário customizar este padrão para atender as necessidades da aplicação, confira como é simples realizar esta tarefa.

Como apresentado aqui algumas vezes, o ASP.NET Identity é um componente muito completo e simples de customizar, ele é escrito baseado no conceito Code-First e sua arquitetura é bem aberta possibilitando a customização de funcionalidades, comportamentos e até mesmo fonte de dados.

As tabelas que o ASP.NET Identity cria automaticamente segue o mesmo processo de qualquer desenvolvimento Code-First, permitindo que o desenvolvedor mapeie na configuração do DbContext toda a modelagem da base que será criada.

Vamos abordar de forma muito simples e pontual como realizar este processo partindo do pré-suposto que sua aplicação foi criada com base no template de aplicação ASP.NET MVC já com o ASP.NET Identity configurado. Independente deste fato, o que é realmente necessário fazer é editar o contexto do ASP.NET Identity.

Uma dica válida para qualquer situação é manter sempre o contexto do ASP.NET Identity separado do contexto da aplicação.

Iremos trabalhar também com a hipótese de customização do IdentityUser através de sua classe derivada ApplicationUser. Vamos ao código.

public class ApplicationUser : IdentityUser
{
    public string Apelido { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<IdentityUser>()
            .ToTable("Usuarios")
            .Property(p => p.Id)
            .HasColumnName("UsuarioId");

        modelBuilder.Entity<ApplicationUser>()
            .ToTable("Usuarios")
            .Property(p => p.Id)
            .HasColumnName("UsuarioId");

        modelBuilder.Entity<IdentityUserRole>()
            .ToTable("UsuarioPapel");

        modelBuilder.Entity<IdentityUserLogin>()
            .ToTable("Logins");

        modelBuilder.Entity<IdentityUserClaim>()
            .ToTable("Claims");

        modelBuilder.Entity<IdentityRole>()
            .ToTable("Papeis");
    }
}

Na classe ApplicationUser realizamos uma pequena customização adicionando um novo campo (Apelido), apenas para enfatizar a situação.

Na classe ApplicationDbContext repare que ela herda de IdentityDbContext, que é a real classe de contexto do ASP.NET Identity onde ela internamente herda de DbContext.

A ideia de existir a classe ApplicationDbContext é justamente fornecer um contexto para customização, uma vez que a classe IdentityDbContext faz parte dos assemblies do ASP.NET Identity e não é possível ser alterada.

Baseado no conceito da herança o que basicamente fizemos foi sobrescrever o método OnModelCreating da classe base para alterarmos os padrões de nomenclatura. Utilizamos Fluent API para realizar esse mapeamento trocando os nomes das tabelas e campos.

Essa troca não impacta no funcionamento interno do ASP.NET Identity, pois as classes internas permanecem intactas, apenas o mapeamento do modelo objeto / relacional foi modificado e a aplicação irá seguir o que a modelagem manda.


modelBuilder.Entity<IdentityUser>()
    .ToTable("Usuarios")
    .Property(p => p.Id)
    .HasColumnName("UsuarioId");

modelBuilder.Entity<ApplicationUser>()
    .ToTable("Usuarios")
    .Property(p => p.Id)
    .HasColumnName("UsuarioId");

Repare que as duas classes (IdentityUserApplicationUser) foram mapeadas para mesma tabela, pois só assim seria possível mapear a classe de usuários e ao mesmo tempo aplicar as customizações, no final tudo vira uma única tabela com informações de ambas as classes.

ASP.NET Identity Tabelas e Campos Customizados

Detalhes adicionais

  • É possível utilizar todos os recursos do Fluent API nessa abordagem, sendo possível modificar tipo dos campos, inserir índices, criar novos relacionamentos, mapear novas tabelas e etc.
  • É possível realizar todo este mapeamento em uma outra classe e configurar esta classe no contexto (assim como fazemos com as nossas entidades no Fluent API).

Simples?
Agora é possível incorporar o ASP.NET Identity ao seu modelo já existente de base de usuários, a única premissa é que todas as tabelas e campos do ASP.NET Identity sejam representados (mapeados) de alguma forma no banco de dados existente.

Vamos continuar a enriquecer este artigo participando nos comentários abaixo com dúvidas, complementos e feedbacks.

Referências

Este artigo foi escrito durante minha participação na Campus Party 2015 #CPBR8

Tutorial ASP.NET MVC 5 + DDD + EF + AutoMapper + IoC + Dicas e Truques

Arquitetura de Sistemas Corporativos é um tema muito menos explorado do que ASP.NET MVC 5 e nem por isso é menos importante (na verdade é bem mais), neste vídeo tutorial eu mostrarei como criar uma arquitetura padrão DDD utilizando ASP.NET MVC 5.2, Entity Framework, AutoMapper, IoC com Ninject e muitas dicas para criar uma arquitetura modelo e totalmente responsável.

ASP.NET MVC 5 + DDD + EF + AutoMapper + IoC

Como poderão acompanhar nos slides e no vídeo ASP.NET MVC é apenas a ponta do iceberg em uma aplicação corporativa. Quando entramos no mundo real os exemplos dos artigos de sites e livros não nos atendem mais e é necessário buscar mais conhecimento para criar uma aplicação robusta, responsável, testável, escalável e de fácil manutenção.

O modelo DDD (Domain Driven Design) atende muito bem cenários de aplicações corporativas e eu utilizo muito em meus projetos profissionais e pessoais.

Neste vídeo tutorial você aprenderá

  • Criar uma solução padrão DDD
  • Separar a aplicação em camadas
  • Entidades de Domínio
  • Classes de Serviço
  • Criar Contratos (Interfaces)
  • Repositório Genérico
  • Repositório Especializado
  • Criar um Contexto do Entity Framework
  • Trabalhar com Migrations
  • Criar novas convenções do Entity Framework
  • Remover algumas convenções do Entity Framework
  • Sobrescrever o método SaveChanges para persistência de dados
  • Programar com CodeFirst
  • Utilizar FluentAPI para modelar tabelas
  • Criar Relacionamentos entre Entidades e refletindo nas tabelas do banco de dados.
  • Criar e utilizar a camada de Application
  • Trabalhar com classes genéricas de Entidades
  • Abstrair camadas com Injeção de Dependência (IoC)
  • Implementar o Ninject como container de IoC (DI)
  • Utilizar ViewModels
  • Utilizar DataAnnotations para validação de formulários
  • Mapear ViewModels x Entidade de Domínio com AutoMapper
  • Muitas dicas para acelerar sua produção

Este conteúdo é aplicado no meu curso de ASP.NET MVC 5 – Enterprise Applications com uma carga horária de 16 horas, com todo o embasamento teórico, técnico e prático, muitos outros patterns, testes, mocks, serviços REST, manipulação de filtros do ASP.NET MVC e etc são abordados no curso para uma preparação completa do futuro arquiteto desenvolvedor.

SLIDES

VÍDEO (3h00 de duração)

* Assine meu canal no Youtube 🙂

SOURCE

Para download do projeto clique aqui (logo será transferido para o GitHub)

Referências

Vamos continuar enriquecendo o assunto, poste aqui sua opinião ou dúvida 😉

Uma técnica simples para utilizar DropDownList no ASP.NET MVC

Utilizar o HtmlHelper para criar um DropDownList em uma View do ASP.NET MVC pode ser um desafio para iniciantes em MVC, veja como facilitar seu trabalho utilizando uma técnica simples.

Existem diversas formas de popular e controlar o estado de um DropDownList gerado pelo HtmlHelper, algumas podem dar um certo trabalho e confundir o programador que está iniciando com ASP.NET MVC e ainda não dominou todas as técnicas.

Conforme o código a seguir, criamos na pasta Models uma classe chamada Cliente que será utilizada para popular um DropDownList, observe que foi criado um método que retorna uma lista de clientes pré definidos (apenas para facilitar a demonstração).

using System.Collections.Generic;

namespace DropDownList.Models
{
    public class Cliente
    {
        public int ClienteId { get; set; }
        public string Nome { get; set; }

        public List<Cliente> ListaClientes()
        {
            return new List<Cliente>
            {
                new Cliente { ClienteId = 1, Nome = "Eduardo Pires"},
                new Cliente { ClienteId = 2, Nome = "João Silva"},
                new Cliente { ClienteId = 3, Nome = "Fulano de Tal"}
            };
        }
    }
}

A classe de Controller possui dois ActionResults, um para Get e um para Post, no primeiro ActionResult é criada uma ViewBag utilizando um nome que facilite o entendimento (no caso o ClienteId).

Esta ViewBag recebe uma estrutura DropDownList que é criada através da classe SelectList e os parâmetros utilizados são: Source, Value, Name (Origem do dado [Método ListarClientes], valor do elemento e nome a ser exibido). Estes parâmetros precisam coincidir com as propriedades da estrutura do seu dado (classe Cliente).

using System.Web.Mvc;
using DropDownList.Models;

namespace DropDownList.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            // Criando uma ViewBag com uma lista de clientes.
            // Utilizo o nome da ViewBag com ClienteId apenas
            // para facilitar o entendimento do código
            // new SelectList significa retornar uma
            // estrutura de DropDownList
            ViewBag.ClienteId = new SelectList
                (
                    new Cliente().ListaClientes(),
                    "ClienteId",
                    "Nome"
                );

            return View();
        }

        [HttpPost]
        // No Post o valor selecionado do DropDownList
        // será recebido no parametro clienteId
        public ActionResult Index(string clienteId)
        {
            // O quarto parametro "clienteId" diz qual é o ID
            // que deve vir pré-selecionado ao montar o DropDownList
            ViewBag.ClienteId = new SelectList
                (
                    new Cliente().ListaClientes(),
                    "ClienteId",
                    "Nome",
                    clienteId
                );

            return View();
        }
    }
}

Ao observar o retorno da criação do SelectList no Quick Watch fica mais fácil de entender a estrutura retornada

DropDownList ASP.NET MVC

Para o Razor HtmlHelper criar corretamente seu DropDownList basta informar (no formato String) o nome da ViewBag que contém a estrutura de dados, foi adicionado um segundo parâmetro para criar um elemento em branco na primeira posição, assim evitando que o primeiro item seja selecionado por engano.

@{
    ViewBag.Title = "Teste DropDownList";
}

@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    <div>
        <h4>@ViewBag.Title</h4>
    </div>
    <div class="row">
        <div class="col-md-8">
            Escolha o cliente:
            @* Passando o Nome da ViewBag *@
            @Html.DropDownList("ClienteId", String.Empty)

            <input type="submit" value="Enviar" class="btn btn-default" />
        </div>
    </div>
}

O resultado ficará assim

DropDownList ASP.NET MVC

A View possui um Form que fará um post para a segunda ActionResult da Controller que já espera receber o valor do item selecionado no DropDownList, o mesmo processo é repetido só que no final da criação da estrutura da SelectList é repassado mais um parâmetro que é o valor do item que foi selecionado na tela anterior, esse parâmetro garante que o foco da seleção mantenha-se no item que foi previamente selecionado.

Com isso vimos que é muito simples utilizar o DropDownList utilizando esta técnica, caso queira treinar basta criar um projeto simples ASP.NET MVC e implementar o código disponibilizado aqui.

Caso desconheça o uso de ViewBag leia este meu artigo que explica os conceitos:
ASP.Net MVC – ViewData, ViewBag e TempData

Até a próxima! 😉

Apresentação do ASP.NET vNext em Goiânia.

Estive em Goiânia no dia 26/07 para apresentar o ASP.NET vNext, uma palestra de 4h00 de duração, evento gratuito.

Recebi do líder da comunidade Override IT o convite para palestrar sobre ASP.NET vNext, foi o assunto escolhido e votado internamente na comunidade para que fosse apresentado.

Palestra ASP.NET vNext

Viajei para Goiânia no dia 25 a tarde e no dia 26 apresentei o tema do início da manhã até a tarde, foram 4h00 de duração. O evento foi realizado no espaço Ponto Get Coworking, e cerca de 40 pessoas estiveram presentes para conhecer tudo o que vai acontecer em breve com o ASP.NET.

Na primeira parte da apresentação contei sobre a história do ASP.NET, seus problemas e limitações com o System.Web, apresentei o OWIN, Katana Project e o Project Helios, e expliquei como tudo isso revolucionou o ASP.NET

Na segunda parte fiz uma espécie de hands-on demonstrando como instalar, configurar e rodar o ASP.NET vNext, o que é e como funciona o KVM e o Core Framework, apresentei também o Visual Studio 2014 e as novidades do ASP.NET MVC 6, rodamos o ASP.NET com IIS, CustomHost, OwinHost e Helios.

Houve um intervalo para coffee break onde pude conhecer um pouco mais alguns participantes, estes tipos de eventos fora do estado são muito bons, pois aproximam e apresentam pessoas que possivelmente manteriam contato apenas por internet.

O resultado foi muito bom, os participantes interagiram durante a apresentação, tirando dúvidas e fazendo comentários. O ASP.NET vNext mudou muito o que conhecemos sobre ASP.NET e com certeza esse tipo de evento antes do lançamento oficial da tecnologia é de grande valor para preparar e capacitar antecipadamente mais profissionais que buscam estar alinhados com as novidades e prontos para novos desafios.

No final sorteamos alguns brindes e eu ofereci uma inscrição gratuita para meu curso Online de ASP.NET MVC 5 – Enterprise Applications que foi sorteada entre os presentes.

Faça em sua cidade

Caso você queira realizar este tipo de evento sobre ASP.NET ou algum outro tema correlato em sua cidade, entre em contato comigo.

Agradecimentos ao Marcelo Paiva pelo convite e a todos os membros da comunidade Override IT.

Referências

Visual Studio 2014 – ASP.NET vNext MVC 6

A Microsoft disponibilizou para download no dia 03/06/14 Visual Studio 2014 CTP – Community Technology Preview (build 14.0.21730.1) que tem como principal novidade o suporte para o ASP.NET vNext.

Visual Studio 2014 - ASP.NET vNext - MVC 6

A versão final do Visual Studio 2014 tem lançamento previsto para 2015, mas até então não existe nada definido oficialmente. É uma versão inicial de testes e outras consecutivas devem surgir antes do lançamento da versão final (RTM).

As principais novidades do Visual Studio 2014

  • Suporte à projetos ASP.NET vNext
  • Suporte à nova plataforma de “Managed Code” – Rosyln
  • Novidades e melhorias para C++

Para quem quer experimentar a nova versão do Visual Studio 2014, uma importante recomendação, ele não suporta funcionamento “lado-a-lado” com Visual Studio 2013, seria necessário desinstalar a versão anterior, por ser uma versão de testes não recomenda-se o uso profissional, instale-o em uma máquina virtual e utilize apenas com o propósito de testes.

Para as próximas versões espera-se compatibilidade com as outras instalações do Visual Studio.

Novidades do suporte ao novo ASP.NET vNext

  • ASP.NET vNext Templates
  • ASP.NET vNext Project.json IntelliSense Support
  • Edição de código fonte sem necessidade de parar a aplicação, atualizando apenas com um refresh do browser, funcionalidade obtida através do Roslyn
  • Todos os arquivos incluídos no projeto, no caso de modificação na estrutura de arquivos, estes serão incluidos e atualizados automaticamente.
  • Restore automático de pacotes NuGet através do intellisense do arquivo project.json
  • Métodos de publicação no Microsoft Azure e via File System
  • Suporte à nova versão do ASP.NET Identity 2.0

Caso não conheça o ASP.NET vNext atualize-se neste meu artigo
https://www.eduardopires.net.br/2014/05/o-futuro-do-asp-net-vnext-mvc-6/

Assista ao vídeo (1h05m) com os primeiros passos no ASP.NET vNext utilizando o Visual Studio 2014

  • Novo Visual Studio 2014
  • Criando uma web aplicação padrão ASP.NET vNext MVC 6
  • Rodando uma web aplicação completa (MVC Music Store) ASP.NET vNext MVC 6
  • Novidades do ASP.NET vNext MVC 6 (ViewComponent, Authorize Claims, etc)
  • Hosting (IIS Express, SelfHost, Console Application)

Este vídeo foi dos primeiros passos tanto em ASP.NET vNext como no Visual Studio 2014, muita coisa pode surgir e mudar, todas serão divulgadas conforme anunciadas.

Referências

Vamos continuar a troca de conhecimentos, escreva seu comentário abaixo 😉