Buscar

ASP.NET MVC 2016

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 28 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 28 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 28 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

ASP.NET MVC: Compreendendo Models, Views e Controllers	1
Criando uma aplicação com o Framework ASP.NET MVC 3	2
ASPNET.MVC - Criação da camada Model	6
Criando um controlador	11
Criando um View Model	17
Criando uma Partial View	22
DropDownList em cascada com JQuery	27
ASP.NET MVC: Compreendendo Models, Views e Controllers
O modelo MVC é muito usado em aplicações para  Web, onde a View é geralmente a página  HTML, e o código que gera os dados dinâmicos para dentro do HTML é o Controller. E, por fim, o Model é representado pelo conteúdo de fato, geralmente armazenado em bancos de dados.
Ainda que existam diferentes formas de MVC, o controle de fluxo geralmente funciona como segue:
O usuário interage com a interface de alguma forma (por exemplo, o usuário aperta um botão)
 O Controller manipula o evento da interface do usuário através de uma rotina pré-escrita.
O Controller acessa o Model, possivelmente atualizando-o de uma maneira apropriada, baseado na interação do usuário (por exemplo, atualizando os dados de cadastro do usuário)
Algumas implementações de View utilizam o Model para gerar uma interface apropriada (por exemplo, mostrando na tela os dados que foram alterados juntamente com uma confirmação). O View obtém seus próprios dados do Model. O Model não toma conhecimento direto da View.
A interface do usuário espera por próximas interações, que iniciarão o ciclo novamente.
Referências: 
http://pt.wikipedia.org/wiki/MVC
http://imasters.com.br/artigo/12139/asp/asp_net_mvc_compreendendo_models_views_e_controllers/
http://imasters.com.br/artigo/23474/dotnet/asp-net-mvc-3-criando-uma-aplicacao-asp-net-mvc3-parte-01
Veja as outras partes do artigo/tutorial.
Criando uma aplicação com o Framework ASP.NET MVC
Criar o projeto ASPNET.MVC
Abra o Visual Studio e no menu File clique em New Project. A seguir, selecione o template para a linguagem Visual C# -> Web e depois o modelo ASP .NET MVC 4 Web Application. Crie a aplicação com o nome ERP.
A seguir, selecione a opção Internet Application, como View Engine o Razor. Vamos usar também o HTML5. Clique em OK
Será criado um projeto que pode ser visto na janela Solution Explorer com a seguinte estrutura:
O framework ASP.NET MVC utiliza uma abordagem baseada em convenções, ao contrário de outros frameworks que utilizam configuração, o que se reflete nos nomes das pastas que utiliza.
Conteúdo de cada pasta para a solução criada.
- Content. Esta pasta é a localização recomendada para adicionar arquivos com conteúdo estático, tais como CSS (cascading style sheet), imagens.
- Controllers. Esta pasta armazena as classes de controle (controladores), os quais são responsáveis, em uma aplicação MVC, por receber as entradas dos usuários, manipular o modelo e escolher uma view para renderizar o conteúdo. 
	O framework ASP.NET MVC requer que o nome de todos os controladores terminar com "Controller"—por exemplo, HomeController, LoginController, or ProductController.
- Models. Nesta pasta são armazenadas as classes que representam o modelo da aplicação. O arquivo EDMX, como veremos mais tarde fica armazenado aqui.
- Scripts. Pasta recomendada para armazenar os arquivos JavaScript de uma aplicação.
- Views. Esta pasta é a localização recomendada para as views, os componentes responsáveis pelo interface com o usuário. Uma subpasta é criada para cada controlador, com o nome do prefix do controlador, por exemplo, se temos um controller chamado HomeController, haverá uma subpasta dentro da pasta Views com o nome Home. Por padrão, quando ASP.NET MVC carrega uma view, ele procura por um arquivo .aspx com o nome (Views\[ControllerName]\[Action].aspx) ou (Views\[ControllerName]\[Action].cshtml) para views Razor. 
- Views\Shared. Por padrão, há também uma pasta chamada Shared na pasta Views, a qual não corresponde a nenhum controller. As pasta Shared é usada para views que são utilizadas/compartilhadas por vários controllers. Por exemplo, uma master page (ou layout em Razor).
	Além das pastas listadas, uma aplicação ASP.NET MVC utiliza o arquivo Global.asax para definir rotas de URL.
ASPNET.MVC - Criação da camada Model
Trabalhares em torno do DER abaixo. 
Observações sobre o modelo: 
- Cadastro de Clientes e Fornecedores: pessoa física e pessoa jurídica são especializações de pessoa. Cliente e fornecedor podem ser pessoas físicas ou jurídicas, assim estão relacionados diretamente a Pessoa.
- Cadastro de Itens (Produto/Serviço): cada item deve estar associado a uma unidade (kg, caixa, unidade, dúzia, etc.), a uma linha de itens (produtos alimentícios, vestuário, material de escritório, etc.) e a um tipo de item (Serviço, Produto Acabado, Componente, Matéria-Prima, etc.)
- Tipos de Movimento: tabela para cadastro das operações a serem feitas com os itens, como Compra, Venda ou Produção. Considere o cadastro inicial dos seguintes tipos de movimento:
- Movimentação de itens (compra, venda, produção, etc.): a movimentação deve estar associada a uma pessoa (cliente ou fornecedor) e também a uma forma de pagamento. Cada movimento poderá gerar um ou mais lançamentos financeiros; para pagamentos parcelados deverá registrar a identificação da parcela (idparcela). A movimentação de itens será também a base para que possamos controlar o estoque.
- O lançamento financeiro, que poderá ser “a pagar” (tipo 1) ou “a receber” (tipo 2) poderá estar associado a um movimento. Se não estiver vinculado ao movimento, deverá estar associado a uma conta e a uma pessoa. Uma conta pode ser descrita como a pagar, a receber ou ambos.
- Cadastro de funcionários: vamos controlar a folha de pagamento, de forma simplificada. Para isso precisamos de um cadastro dos funcionários que contenha: dados pessoais, data de admissão, data de demissão, salário. O registro de pagamento de cada mês para cada funcionário deverá ser feito. Deveremos ainda registrar o setor em que cada funcionário trabalha e a função que exerce, bem como os possíveis reajustes de salário de cada funcionário.
Após criar o modelo, insira pelo menos um registro em cada tabela criada e faça as seguintes consultas SQL:
Todos os clientes que são pessoas jurídicas.
Os fornecedores da cidade de São Paulo.
Todas as compras feitas pela empresa, por fornecedor (operação de compra).
Os clientes que efetuaram o maior número de compra (operação de venda).
Os clientes que efetuaram o maior valor de compra (operação de venda).
O valor pago aos funcionários, por mês.
O salário dos funcionários que trabalham no departamento 1, em ordem decrescente.
Todos os lançamentos a pagar que vencerão no mês 05/2016.
Os clientes que não efetuaram compras no mês 03/2016.
Todos os itens cuja quantidade esteja menos de 10% acima da quantidade mínima.
Exercício – ASP.NET MVC (Modelo)
Crie as classes de modelo para o banco ERP, fazendo as anotações necessárias para a geração do banco de dados.
Use as seguintes anotações:
[Key]
[Required(ErrorMessage = "Mensagem de erro")]
[Display(Name="Nome do Campo que será mostrado nas views")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
[MinLength(5, ErrorMessage = "O tamanho mínimo do nome são 5 caracteres.")]
[MaxLength(200, ErrorMessage = "O tamanho máximo são 200 caracteres.")]
[Range(3, 500, ErrorMessage = "O valor deverá ser entre 3 e 500.")]
Exemplo:
 public class Estado
 {
 [Key]
 public int IdEstado { get; set; }
 [Required(ErrorMessage="Nome Obrigatório")]
 [StringLength(60)]
 public string Nome { get; set; }
 [StringLength(2)]
 public string Sigla { get; set; }
 public ICollection<Cidade> Cidades { get; set; }
 }
 public class Cidade
 {
 [Key]
 public int IdCidade { get; set; }
 public string Nome { get; set; }
 [Required]
 public int IdEstado { get; set; }
 [ForeignKey("IdEstado")]
 public Estado Estado { get; set; }
 }
Veja a explicação de cada atributo:Key – define que tal propriedade é a chave primária.
Column – é o número da ordem em que a propriedade será criada fisicamente no banco de dados.
Required – significa campo obrigatório, ou seja, caso o internauta não digitar, será mostrada a mensagem definida em ErrorMessage. Desta forma, quando o banco de dados for gerado, a propriedade Allow Null será falso.
MinLength – informa qual é o tamanho mínimo do respectivo campo. Caso a regra seja violada, será exibida a mensagem no ErrorMessage.
StringLength ou MaxLength – é o tamanho máximo do campo, inclusive o número atribuído será o MaxLength do campo no banco de dados.
Display – é o nome a ser mostrado em todas as interfaces de usuário. Nem sempre o nome da propriedade é o melhor texto a ser mostrado na UI, portanto, você pode alterar.
DisplayFormat – é o formato a ser exibido na UI. O ApplyFormatInEditMode indica se o formato deverá ser usado quando entrar no modo de edição. O NullDisplayText indica qual é o texto a ser mostrado quando o campo for nulo.
Range – define a faixa de dados aceita pela propriedade. Caso esteja fora da faixa é mostrado o ErrorMessage.
Fonte: http://msdn.microsoft.com/pt-br/library/jj129537.aspx
É necessário definir a conexão no arquivo Web.config, na seção <connectionStrings>:
 <connectionStrings>
 <!--<add name="ERP" 
 providerName="System.Data.SqlClient" 
 connectionString="Server=.;Database=ERP1;Integrated Security=True" 
 />-->
 <add
 name="ERP"
 providerName="System.Data.SqlClient"
 connectionString="Server=.;
 Database=ERP2014;
 Trusted_Connection=false;
 User Id=sa;
 Password=fepam;
 Persist Security Info=true;
 MultipleActiveResultSets=True" />
 </connectionStrings>
Também é necessário criar uma classe de contexto de banco de dados (database contexto), que é a classe que coordena as funcionalidades do Entity Framework para um dado modelo de dados 
 public class ERPContext : DbContext
 {
 public ERPContext() : base("ERP")
 {
 Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ERPContext>());
 }
 public DbSet<Estado> Estados { get; set; }
 public DbSet<Cidade> Cidades { get; set; }
 public DbSet<Pessoa> Pessoas { get; set; }
 public DbSet<Lancamento> Lancamentos { get; set; }
 public DbSet<PessoaFisica> PessoasFisicas { get; set; }
 public DbSet<PessoaJuridica> PessoasJuridicas { get; set; }
 public DbSet<Cliente> Clientes { get; set; }
 }
Sobrescreva o método OnModelCreating, presente na superclasse DbContext, para gerar as tabelas que herdam da classe Pessoa:
 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
 // Remover pluralização do nome das tabelas
 modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
 //Herança Table per Type. Default é Table Per Hierarchy
 modelBuilder.Entity<pessoa>().ToTable("pessoa");
 modelBuilder.Entity<pessoafisica>().ToTable("pessoafisica");
 modelBuilder.Entity<pessoajuridica>().ToTable("pessoajuridica");
 modelBuilder.Entity<funcionario>().ToTable("funcionario");
 }
Chame um controlador que modele um das classes, como feito em sala de aula, e verifique o banco gerado no SQL Server. Gere um DER no SQL Server e compare com o DER do ERP .
Criando um controlador
A interação do usuário com as aplicações ASP.NET MVC é organizada em torno dos controllers (controladores) e suas actions (ações, métodos).
Antes de criar um controlador, dê um build no projeto para fazer com que o modelo e as classes do contexto estejam disponíveis para o controller
Para criar um controller, clique com o botão direito do mouse sobre a pasta Controllers do projeto selecione Add e clique em Controller. A seguir, na janela Add Controller, faça as seleções conforme a figura a seguir:
Ao confirmar, será gerado um Controlador com o seguinte código:
Documento em elaboração: José dos Reis Mota – 2015 (jreismota@gmail.com) 
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ERP.Models;
namespace ERP.Controllers
{
 public class CidadeController : Controller
 {
 private ERPEntities db = new ERPEntities();
 //
 // GET: /Cidade/
 /* Por padrão, se não for informado o método HTTP, é utilizado o método GET */
 public ViewResult Index()
 {
 /* 
 Recupera uma lista de cidades a partir da instância da classe de contexto
 */
 // var cidade = db.Cidade.Include("Estado");
 /* Observe na linha abaixo o uso da LINQ (language-integrated query) que permite recuperar objetos a partir do banco de dados */
 var cidade = from c in db.Cidade
 where c.Estado.Sigla == "MG"
 orderby c.Nome ascending
 select c;
 /* Converte os objetos em uma lista, que é recuperada na view Index */
 return View(cidade.ToList());
 }
 //
 // GET: /Cidade/Details/5
 /* Observe que a action abaixo recebe um parâmetro, por meio da URL acima. Isso é possível graças às rotas estabelecidas no arquivo Global.asax.
 */
 public ViewResult Details(int id)
 {
 /* O parâmetro recebido é empregado em uma consulta LINQ, que utiliza uma expressão Lambda e recupera um objeto cidade, retornado para a View.*/
 Cidade cidade = db.Cidade.Single(c => c.IdCidade == id);
 return View(cidade);
 }
 //
 // GET: /Cidade/Create
 public ActionResult Create()
 {
 /* A ViewBag é uma propriedade que permite enviar dados do controller para a view. 
 * Nesse caso, é enviada uma lista de estados que preencherá uma combobox na view. 
 */
 ViewBag.IdEstado = new SelectList(db.Estado, "IdEstado", "Nome");
 return View();
 /* Veja nos links abaixo informações sobre mecanismos de transferência de dados em ASP.NET MVC:
 * http://blog.felipeoriani.com.br/post/2011/09/06/ASPNET-MVC-Quando-utilizar-ViewBag-ViewData-TempData.aspx
 * http://weblogs.asp.net/hajan/archive/2010/12/11/viewbag-dynamic-in-asp-net-mvc-3-rc-2.aspx
 * */
 
 }
 //
 // POST: /Cidade/Create
 /* O metódo HTTP GET para a action Create retorna um formulário em branco, com um combobox preenchido com os Estados.
 * Já o anotação abaixo especifica o método HTTP Post para envio dos dados do formulário. 
 * Veja que o parâmetro recebido é um objeto Cidade, o que é possível graças à atribuição do comando na view: @model ERP.Models.Cidade
 * */
 [HttpPost]
 public ActionResult Create(Cidade cidade)
 {
 /* O código abaixo verifica se o modelo é válido, de acordo com as regras de validação definidas. 
 * O EF4 automaticamente busca as validações de acordo com a definição do modelo de dados. Por exemplo: um campo que não pode ser nulo
 * Se o modelo é valido, o objeto é adicionado ao contexto (nesse momomento, o objeto ainda não está persistido (gravado) no banco.
 * A gravação no banco de dados é feita ao chamar o método SaveChanges().
 * Observe que após a gravação, o sistema redireciona para a action Index.
 */
 if (ModelState.IsValid)
 {
 db.Cidade.AddObject(cidade);
 db.SaveChanges();
 return RedirectToAction("Index");
 }
 /* Esse código será executado se o modelo não for válido.* Nesse caso uma lista de Estados é retornada pelo propriedade ViewBag e a view cidade é mostrada com os erros de validação 
 */
 ViewBag.IdEstado = new SelectList(db.Estado, "IdEstado", "Nome", cidade.IdEstado);
 return View(cidade);
 }
 //
 // GET: /Cidade/Edit/5
 public ActionResult Edit(int id)
 {
 Cidade cidade = db.Cidade.Single(c => c.IdCidade == id);
 ViewBag.IdEstado = new SelectList(db.Estado, "IdEstado", "Nome", cidade.IdEstado);
 return View(cidade);
 }
 //
 // POST: /Cidade/Edit/5
 [HttpPost]
 public ActionResult Edit(Cidade cidade)
 {
 if (ModelState.IsValid)
 {
 db.Cidade.Attach(cidade);
 db.ObjectStateManager.ChangeObjectState(cidade, EntityState.Modified);
 //db.Entry(cidade).State = EntityState.Modified;
 db.SaveChanges();
 return RedirectToAction("Index");
 }
 ViewBag.IdEstado = new SelectList(db.Estado, "IdEstado", "Nome", cidade.IdEstado);
 return View(cidade);
 }
 //
 // GET: /Cidade/Delete/5
 public ActionResult Delete(int id)
 {
 Cidade cidade = db.Cidade.Single(c => c.IdCidade == id);
 return View(cidade);
 }
 //
 // POST: /Cidade/Delete/5
 [HttpPost, ActionName("Delete")]
 public ActionResult DeleteConfirmed(int id)
 {
 Cidade cidade = db.Cidade.Single(c => c.IdCidade == id);
 db.Cidade.DeleteObject(cidade);
 db.SaveChanges();
 return RedirectToAction("Index");
 }
 /* Esse método permite liberar os recursos utilizados pela classe quando não forem mais necessários. */
 protected override void Dispose(bool disposing)
 {
 db.Dispose();
 base.Dispose(disposing);
 }
 }
}
Vamos executar e analisar o código dos métodos criados no controlador acima, assim com das views criadas na pasta \Views\Cidade para entendermos como ele funciona.
Por meio da instância do dbContext, temos acesso às entidades e seus relacionamentos, assim como às operações que podem ser efetuadas sobre eles, como as operações CRUD.
 private ERPEntities db = new ERPEntities();
Exercício: Explique por que existem dois métodos (actions) para Create, Edit e Delete.
Vamos agora criar um controlador para a classe Funcionário. Antes dê um Build no projeto para compilar as alterações.
Como a classe funcionário herda de Pessoa Física, que herda de Pessoa, deve ocorrer alguns problemas de referência. Mude as referências para a classe funcionário. A referência pode ser feita diretamente pela classe funcionário ou pelo método OfType<>, conforme abaixo.
Pessoa.OfType<Funcionario>(), para que a relação de herança funcione.
Exemplo: 
 public ViewResult Index()
 {
 //var pessoa = db.Pessoa.Include("Cidade").Include("Cargo").Include("Departamento");
 var funcionario = db.Pessoa.OfType<Funcionario>().Include("Cargo").Include("Departamento");
 return View(funcionario.ToList());
 }
No próximo tutorial trataremos do cadastro de Clientes e Fornecedores.
Criando um View Model
ViewModel é um padrão utilizado que permite a um Controlador empacotar todos os dados de que necessita para gerar uma resposta apropriada na visão. No projeto ERP em que estamos trabalhando, vamos criar um controlador que coordena as funcionalidades do cadastro de Clientes, que está relacionada à entidade Pessoa. No entanto, um cliente pode ser uma Pessoa Física ou uma Pessoa Jurídica. Como não temos herança múltipla em C#, utilizaremos o conceito de composição de objetos, encapsulando todas as entidades que serão necessárias para fazer a manutenção do cadastro de Clientes, utilizando o padrão ViewModel. 
Vamos definir o seguinte: a listagem pode ser feita utilizando apenas os dados da entidade Pessoa. Teremos um link para criar um novo “Cliente Pessoa Física” e outro para cadastrar um novo “Cliente Pessoa Jurídica”; assim evitaremos erros de validação. Na edição de um cliente, o próprio sistema deve verificar o tipo da pessoa (Física ou Jurídica) e retornar a view com o formulário adequado a cada tipo. Vamos também definir que no cadastro de cliente deveremos inserir a informação se o cliente é um cliente preferencial (acrescente esse atributo à classe Cliente).
Agora, siga as seguintes instruções:
Crie uma nova pasta no projeto, com o nome: ViewModels.
Adicione uma nova classe com o nome ClienteViewModel.
Adicione as propriedades necessárias, cujos valores poderão ser acessados a partir das Views, juntamente com o método construtor da classe. Sua classe deverá conter o seguinte código:
 public class ClienteViewModel
 {
 public Cliente Cliente {get; set;}
 public PessoaFisica PessoaFisica { get; set; }
 public PessoaJuridica PessoaJuridica { get; set; }
 public ClienteViewModel(Cliente cliente, PessoaFisica pf)
 {
 Cliente = cliente;
 PessoaFisica = pf;
 }
 public ClienteViewModel(Cliente cliente, PessoaJuridica pj)
 {
 Cliente = cliente;
 PessoaJuridica = pj;
 }
 }
Assim, a propriedade Cliente representa o contato corrente a ser editado/criado, que pode ser uma Pessoa Física ou Pessoa Jurídica. Por isso, fizemos uma sobrecarga do método construtor, para instanciarmos a classe com o tipo de pessoa adequado em cada situação.
Na listagem dos clientes, podemos utilizar apenas os dados genéricos de pessoa, sem os dados específicos de pessoa jurídica ou pessoa física. Para facilitar a criação dessa listagem vamos também criar uma classe para relacionar as entidades Pessoa e Cliente, conforme código abaixo: 
 public class ClientePessoa
 {
 public cliente Cliente { get; set; }
 public pessoa Pessoa { get; set; }
 public ClientePessoa(cliente c, pessoa p)
 {
 Cliente = c;
 Pessoa = p;
 }
 }
Depois disso, vamos declarar um propriedade que represente uma lista (coleção) da classe acima na classe ClienteViewModel, assim como um método construtor que utilize essa propriedade. O código final da Classe ClienteViewModel é mostrado abaixo: 
 public class ClienteViewModel
 {
 public Cliente Cliente { get; set; }
 public PessoaFisica PessoaFisica { get; set; }
 public PessoaJuridica PessoaJuridica { get; set; }
 public IList<ClientePessoa> ClientePessoas { get; set; }
 public ClienteViewModel(Cliente cliente, PessoaFisica pf)
 {
 Cliente = cliente;
 PessoaFisica = pf;
 }
 public ClienteViewModel(Cliente cliente, PessoaJuridica pj)
 {
 Cliente = cliente;
 PessoaJuridica = pj;
 }
 public ClienteViewModel(IList<ClientePessoa> clientePessoa)
 {
 ClientePessoas = clientePessoa;
 }
 }
Vamos agora gerar um controlador para a classe Cliente – ClienteControlller, e, em seguida, modificar as actions desse controlador. Utilizaremos uma consulta LINQ para fazer uma junção (join) entre as entidades Cliente e Pessoa e, ao mesmo tempo, criar a lista correspondente à classe ClientePessoa que utilizaremos para instanciarmos a classe ClienteViewModel. Segue abaixo o código da action Index:
 public ViewResult Index()
 {
 var pessoaCliente =
 (from a in db.cliente
 join b in db.pessoa on a.IdCliente equals b.IdPessoa
 select new ClientePessoa()
 {
 Cliente = a,
 Pessoa = b}).ToList();
 var clienteViewModel = new ClienteViewModel(pessoaCliente);
 return View(clienteViewModel);
 }
Veja o poder da linguagem de consulta LINQ e que podemos utilizar a ideia acima para relacionar diferentes entidades, mesmo que, no modelo, elas não estejam diretamente associadas.
Adicione uma view para gerar a listagem. Clique o botão direito em qualquer parte da action Index e clique em Add View. Selecione as opções conforme figura abaixo: 
Se a classe ClienteViewModel não estiver sendo apresentada, primeiro faça um Build na solução e tente novamente. Será gerada uma view em branco, fortemente-tipada (ClienteViewModel), conforme código abaixo:
@model PCP2012.ViewModels.ClienteViewModel
@{
 ViewBag.Title = "Index";
}
<h2>Index</h2>
Adicione o código para gerar a listagem e uma tabela HTML. Acrescente os campos de pessoa e de cliente, com um laço para percorrer a lista ClientePessoa, instanciada na classe ClienteViewModel. Segue abaixo o código que exibe uma coluna. Crie as demais colunas para a tabela.
<table>
 <tr>
 <th>
 Nome
 </th>
 <th></th>
 </tr>
@foreach (var item in Model.ClientePessoas) {
 <tr>
 <td>
 @Html.DisplayFor(modelItem => item.Pessoa.Nome)
 </td>
 <td>
 @Html.ActionLink("Editar", "Edit", new { id=item.Pessoa.IdPessoa }) |
 @Html.ActionLink("Exibir", "Details", new { id=item.Pessoa.IdPessoa }) |
 @Html.ActionLink("Excluir", "Delete", new { id=item.Pessoa.IdPessoa })
 </td>
 </tr>
}
</table>
Vamos agora tratar a funcionalidade de edição (alteração) de um cliente. Um cliente pode ser pessoa física ou jurídica. Assim, precisamos verificar o tipo pessoa e instanciar a classe ClienteViewModel com o tipo correto. Crie a action Edit (Método Get) na classe ClienteControler, com o código abaixo.
 // GET: /Cliente/Edit/5
 
 public ActionResult Edit(int id = 0)
 {
 cliente cliente = db.cliente.Single(c => c.IdCliente == id);
 pessoa pessoa = db.pessoa.Single(p => p.IdPessoa == id);
 if (cliente == null)
 {
 return HttpNotFound();
 }
 pessoafisica pf = db.pessoa.OfType<pessoafisica>().Single(p => p.IdPessoa == id);
 ClienteViewModel clienteViewModel;
 if (pf == null)
 {
 pessoajuridica pj = db.pessoa.OfType<pessoajuridica>().Single(p => p.IdPessoa == id);
 clienteViewModel = new ClienteViewModel(cliente, pj);
 ViewBag.IdCidade = new SelectList(db.cidade, "idCidade", "Nome", pj.IdCidade);
 }
 else
 {
 clienteViewModel = new ClienteViewModel(cliente, pf);
 ViewBag.IdCidade = new SelectList(db.cidade, "idCidade", "Nome", pf.IdCidade);
 }
 
 return View(clienteViewModel);
 }
Crie a View (fortemente tipada), selecionando a classe de ClienteViewModel. 
Será criada uma View com o seguinte código:
@model PCP2012.ViewModels.ClienteViewModel
@{
 ViewBag.Title = "Edit";
}
<h2>Edit</h2>
Observem que o código da View está praticamente em branco, apenas o título da página e uma tag de subtítulo (<h2>) foram geradas. Isto se deve ao fato de que na classe ClienteViewModel não há propriedades escalares (com tipos primitivos - int, string, float), como nas outras classes que gerávamos até agora. Ou seja, devemos construir o código de nossa view.
Criando uma Partial View
Normalmente, os dados de um formulário são os mesmos para as views de edição/criação. Assim, podemos criar um template compartilhado para essas views, o que chamamos de Partial View. Como podemos editar um Cliente que seja Pessoa Física ou Pessoa Jurídica, criaremos uma partial view para cada um. Antes, adicione à view gerada (Edit), o seguinte código:
@(this.Model.PessoaFisica != null ? Html.Partial("ClientePessoaFisica") : Html.Partial("ClientePessoaJuridica"));
O código acima verifica se existe uma instância de PessoaFisica. Se houver, ele renderiza uma Partial View apropriada. Vamos agora criar a PartialView. Uma dica, vamos criá-la do tipo PessoaFisica para aproveitar os campos e apenas alterar e acrescentar as informações necessárias.
Clique com o botão direito na action Edit e preencha os dados conforme figura abaixo:
Será gerada uma view com os dados de uma Pessoa Física, conforme podemos observar no início do código abaixo: 
Vamos alterar a primeira linha para buscar a classe do modelo que representa um ClienteViewModel e fazer as alterações necessárias para a edição/criação de um Cliente.
@model ERP.ViewModels.ClienteViewModel
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
@using (Html.BeginForm("EditPF", "Cliente"))
{
 @Html.ValidationSummary(true)
 <fieldset>
 <legend>pessoafisica</legend>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.DataNascimento)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.DataNascimento)
 @Html.ValidationMessageFor(model => model.PessoaFisica.DataNascimento)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.CPF)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.CPF)
 @Html.ValidationMessageFor(model => model.PessoaFisica.CPF)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.TelefoneResidencial)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.TelefoneResidencial)
 @Html.ValidationMessageFor(model => model.PessoaFisica.TelefoneResidencial)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.RG)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.RG)
 @Html.ValidationMessageFor(model => model.PessoaFisica.RG)
 </div>
 @Html.HiddenFor(model => model.PessoaFisica.IdPessoa)
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.Nome)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.Nome)
 @Html.ValidationMessageFor(model => model.PessoaFisica.Nome)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.DataCadastro)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.DataCadastro)
 @Html.ValidationMessageFor(model => model.PessoaFisica.DataCadastro)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.Rua)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.Rua)
 @Html.ValidationMessageFor(model => model.PessoaFisica.Rua)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.Numero)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.Numero)
 @Html.ValidationMessageFor(model => model.PessoaFisica.Numero)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.bairro)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.bairro)
 @Html.ValidationMessageFor(model => model.PessoaFisica.bairro)</div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.CEP)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.CEP)
 @Html.ValidationMessageFor(model => model.PessoaFisica.CEP)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.TelefoneComercial)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.TelefoneComercial)
 @Html.ValidationMessageFor(model => model.PessoaFisica.TelefoneComercial)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.TelefoneCelular)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.TelefoneCelular)
 @Html.ValidationMessageFor(model => model.PessoaFisica.TelefoneCelular)
 </div>
 <div class="editor-label">
 @Html.LabelFor(model => model.PessoaFisica.IdCidade)
 </div>
 <div class="editor-field">
 @Html.EditorFor(model => model.PessoaFisica.IdCidade)
 @Html.ValidationMessageFor(model => model.PessoaFisica.IdCidade)
 </div>
 <p>
 <input type="submit" value="Save" />
 </p>
 </fieldset>
}
<div>
 @Html.ActionLink("Back to List", "Index")
</div>
Observe a seguinte linha de código:
Html.BeginForm("EditPF","Cliente")
Este HTML helper possui como parâmetros o nome da action, seguida pelo nome do Controller. Portanto, ao submeter os dados do formulário (método Post), será processada a action EditPF. Vamos criá-la conforme código abaixo:
 [HttpPost]
 public ActionResult EditPF([Bind(Prefix = "PessoaFisica")]pessoafisica pf)
 {
 cliente cli = new cliente();
 cli.IdCliente = pf.IdPessoa;
 if (ModelState.IsValid)
 {
 if (pf.IdPessoa > 0)
 {
 db.pessoa.Attach(pf);
 db.Entry(pf).State = System.Data.EntityState.Modified;
 
 }
 else
 {
 db.cliente.Add(cli);
 db.pessoa.Add(pf);
 }
 db.SaveChanges();
 return RedirectToAction("Index");
 }
 if (pf.IdPessoa == 0)
 {
 ViewBag.IdCidade = new SelectList(db.cidade, "IdCidade", "Nome");
 }
 else
 {
 ViewBag.IdCidade = new SelectList(db.cidade, "IdCidade", "Nome", pf.IdCidade);
 }
 cliente cliente = db.cliente.Single(c => c.IdCliente== pf.IdPessoa);
 var clienteViewModel = new ClienteViewModel(cliente, pf);
 ViewBag.IdCidade = new SelectList(db.cidade, "IdCidade", "Nome", pf.IdCidade);
 return View("Edit", clienteViewModel);
 }
O código é semelhante ao que gerávamos até o momento. As diferenças são o uso do código [Bind(Prefix = "PessoaFisica")]PessoaFisica pf, na assinatura do método, que permite ligar os parâmetros recebidos do formulário - nesse caso todos aqueles que possuem o prefixo PessoaFisica - ao objeto PessoaFisica pf. Observe também as modificações na action EditPF para verificar se a operação é o cadastro de um novo cliente (IdPessoa == 0) ou a alteração de um cliente já cadastrado (IdPessoa > 0):
Maiores explicações do Binding: http://www.slideshare.net/nandokakimoto/aspnet-mvc-model-binding
http://odetocode.com/blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx
http://robsoncastilho.wordpress.com/2012/05/06/asp-net-mvc-model-binding-parte-1-defaultmodelbinder/
Observe que não acrescentamos os dados de cliente ao formulário. Tente fazer isso. Crie também a funcionalidade para edição de um cliente pessoa jurídica. 
Crie também dois links na view Index direcionando para a action CreatePF e CreatePJ. 
Tente implementar os códigos necessários para a inserção de clientes. Utilize as partial views já geradas ClientePessoaFisica e ClientePessoaJuridica.
Código da action para inserção de um Cliente Pessoa Física:
 public ActionResult CreatePF()
 {
 ViewBag.IdCidade = new SelectList(db.Cidade, "IdCidade", "Nome");
 PessoaFisica pf = new PessoaFisica();
 pf.DataCadastro = DateTime.Now;
 Cliente c = new Cliente();
 var clienteViewModel = new ClienteViewModel(c, pf);
 return View("Edit", clienteViewModel);
 }
Criação de um campo para informar se o cliente é ou não preferencial na view EditPF: 
@Html.CheckBoxFor(model => model.Cliente.Preferencial)
Inclua também o idPessoa de Cliente como um campo oculto: 
@Html.HiddenFor(model => model.Cliente.IdPessoa)
DropDownList em cascada com JQuery
Neste tutorial, veremos como criar um comportamento em nossa aplicação, de forma que , ao selecionar um estado (UF), automaticamente seja populada uma DropDownList (ComboBox) com as cidades daquele estado.
Discussão técnica: quais os benefícios do desenvolvimento dessa funcionalidade para a aplicação?
Naturalmente, primeiro precisamos do modelo criado, como no caso do projeto que estamos desenvolvemos. Assim, podemos criar uma action para listar as cidades específicas de um estado. Vamos criá-la no controlador de clientes:
 public ActionResult CidadesDoEstado(int idEstado)
 {
 var cidades = db.Cidade.Where(x => x.IdEstado == idEstado).ToList();
 SelectList cidadesLista = new SelectList(cidades, "IdCidade", "Nome");
 return Json(cidadesLista, JsonRequestBehavior.AllowGet);
 }
Observe que a action recebe um parâmetro que corresponde ao código do Estado selecionado na ComboBox e retorna uma lista de cidades desse estado. A action retorna ainda os dados no formato JSON, permitindo que as informações possam ser manipulados por meio de JavaScript/JQuery.[1: Referências sobre JSON:http://www.brnsouza.com/blog/index.php/2009/05/o-que-e-json-como-e-quando-usar/http://www.json.org/http://www.oficinadanet.com.br/artigo/1550/json_-_javascript_object_notation_-_o_que_e]
Como segundo passo, devemos acrescentar o código abaixo na view ClientePessoaFisica, para incluir uma ComboBox para listar os estados:
 <div class="editor-label">
 Estado
 </div>
 <div class="editor-field">
 @Html.DropDownList("IdUF", (SelectList)ViewBag.Estados)
 </div>
A partir da identificação do campo “IdUF”, podemos verificar quando há mudança nesse campo por meio do evento change, conforme o código javascript (JQuery) abaixo, que basicamente utiliza a função getJSON para chamar a action CidadesDoEstado, informando o estado selecionado por meio do trecho $("#IdUF").val(). Após os dados serem retornados pela action CidadesDoEstado no formato JSON, cada linha da lista é percorrida e transformada em uma opção do combobox. Depois disso, é acrescentada na combobox de cidades o html gerado, por meio da linha $("#PessoaFisica_IdCidade").html(itens);[2: Referências sobre JQuery:http://simplesideias.com.br/usando-jquery-na-pratica/http://docs.jquery.com/Main_Pagehttp://visualjquery.com/]
<script type="text/javascript" >
 $("#IdUF").change(function () {
 var loc = window.location.host;
 var url = "http://" + loc + "/Cliente/CidadesDoEstado?idEstado=" + $("#IdUF").val();
 $.getJSON(url,
 function (cidadesLista) {
 var itens = "";
 $.each(cidadesLista, function (i, cidade) {
 itens += "<option value=" + cidade.Value + ">" + cidade.Text + "</option>";
 });
 $("#PessoaFisica_IdCidade").html(itens);
 });
 });
</script>
É necessário ainda ajustar o códigodas actions que chamam a view. Por exemplo, no caso da action Edit, para não passarmos todas as cidades para a view, podemos passar apenas as cidades do estado cuja cidade já estiver armazenada no banco de dados:
 ViewBag.IdCidade = new SelectList(db.Cidade.Where(x => x.IdEstado == pessoa.Cidade.IdEstado), "IdCidade", "Nome", pessoa.IdCidade);
 ViewBag.Estados = new SelectList(db.Estado, "IdEstado", "Nome", pessoa.Cidade.IdEstado);
E na action create (CreatePF), como os dados ainda serão inseridos, podemos passar uma listagem vazia de cidades, que será automaticamente populada ao selecionar um estado:
 var cidades = new List<Cidade>();
 ViewBag.IdCidade = new SelectList(cidades, "IdCidade", "Nome");
 ViewBag.IdUF = new SelectList(db.Estado, "IdEstado", "Nome");
Observem ainda que em caso de submissão de dados do formulário com erros (por exemplo, o nome de um cliente nulo), ocorrerá um erro na validação do modelo e redirecionará novamente para a view Edit, o que exige o mesmo tratamento dado acima. Assim, devemos acrescentar na action EditPF, o código abaixo, que verifica se se trata de um novo registro (IdPessoa == 0), ou seja, uma inserção, ou de um registro existente, ou seja, uma alteração: 
 if (pf.IdPessoa == 0)
 {
 var cidades = new List<Cidade>();
 ViewBag.IdCidade = new SelectList(cidades, "IdCidade", "Nome");
 ViewBag.Estados = new SelectList(db.Estado, "IdEstado", "Nome");
 }
 else
 {
 ViewBag.Estados = new SelectList(db.Estado, "IdEstado", "Nome", pf.Cidade.IdEstado);
 ViewBag.IdCidade = new SelectList(db.Cidade.Where(x => x.IdEstado == pf.Cidade.IdEstado), "IdCidade", "Nome", pf.IdCidade);
 }

Outros materiais