Eu sou novo no ASP.NET MVC. Estou com um problema para entender o objetivo de um ViewModel.
O que é um ViewModel e por que precisamos de um ViewModel para um aplicativo ASP.NET MVC?
Se eu der um bom exemplo sobre o seu funcionamento e explicação, seria melhor.
asp.net-mvc
viewmodel
único
fonte
fonte
Respostas:
A
view model
representa os dados que você deseja exibir em sua exibição / página, seja para texto estático ou para valores de entrada (como caixas de texto e listas suspensas) que podem ser adicionados ao banco de dados (ou editados). É algo diferente do seudomain model
. É um modelo para a vista.Digamos que você tenha uma
Employee
classe que represente o modelo de domínio do funcionário e que contenha as seguintes propriedades (identificador exclusivo, nome, sobrenome e data de criação):Os modelos de exibição diferem dos modelos de domínio, pois os modelos de exibição contêm apenas os dados (representados pelas propriedades) que você deseja usar na exibição. Por exemplo, digamos que você queira adicionar um novo registro de funcionário, seu modelo de exibição pode ficar assim:
Como você pode ver, ele contém apenas duas das propriedades. Essas duas propriedades também estão no modelo de domínio do funcionário. Por que isso você pode perguntar?
Id
pode não ser definido a partir da visualização, pode ser gerado automaticamente pela tabela Employee. EDateCreated
também pode ser definido no procedimento armazenado ou na camada de serviço do seu aplicativo. Portanto,Id
eDateCreated
não é necessário no modelo de exibição. Você pode exibir essas duas propriedades ao exibir os detalhes de um funcionário (um funcionário que já foi capturado) como texto estático.Ao carregar a visualização / página, o método de ação de criação no controlador de funcionário criará uma instância desse modelo de visualização, preencherá todos os campos, se necessário, e passará esse modelo de visualização para a visualização / página:
Sua visualização / página pode ficar assim (supondo que você esteja usando
ASP.NET MVC
e oRazor
mecanismo de visualização):A validação seria feita apenas em
FirstName
eLastName
. Usando o FluentValidation, você pode ter uma validação como esta:E com as Anotações de dados, pode parecer o seguinte:
O principal a lembrar é que o modelo de visualização representa apenas os dados que você deseja usar , nada mais. Você pode imaginar todo o código e validação desnecessários se tiver um modelo de domínio com 30 propriedades e desejar atualizar apenas um único valor. Dado esse cenário, você só teria esse valor / propriedade no modelo de exibição e nem todas as propriedades que estão no objeto de domínio.
Um modelo de visualização pode não ter apenas dados de uma tabela do banco de dados. Pode combinar dados de outra tabela. Veja o meu exemplo acima sobre como adicionar um novo registro de funcionário. Além de adicionar apenas o nome e o sobrenome, você também pode adicionar o departamento do funcionário. Esta lista de departamentos virá da sua
Departments
mesa. Então agora você tem dados das tabelasEmployees
eDepartments
em um modelo de exibição. Você precisará adicionar as duas propriedades a seguir ao seu modelo de exibição e preenchê-lo com dados:Ao editar os dados do funcionário (um funcionário que já foi adicionado ao banco de dados), não difere muito do meu exemplo acima. Crie um modelo de vista, chame-o por exemplo
EditEmployeeViewModel
. Tenha apenas os dados que você deseja editar neste modelo de visualização, como nome e sobrenome. Edite os dados e clique no botão enviar. Eu não me preocuparia muito com oId
campo, porque oId
valor provavelmente estará no URL, por exemplo:Pegue isso
Id
e passe-o para a camada do repositório, juntamente com os valores do seu nome e sobrenome.Ao excluir um registro, normalmente sigo o mesmo caminho do modelo de visualização de edição. Eu também teria um URL, por exemplo:
Quando a visualização é carregada pela primeira vez, eu obtinha os dados do funcionário no banco de dados usando o
Id
3. Eu mostrava texto estático na minha visualização / página para que o usuário pudesse ver qual funcionário está sendo excluído. Quando o usuário clica no botão Excluir, eu usaria oId
valor 3 e o passaria para minha camada de repositório. Você só precisaId
excluir um registro da tabela.Outro ponto, você realmente não precisa de um modelo de visualização para cada ação. Se forem dados simples, seria bom usar apenas
EmployeeViewModel
. Se são vistas / páginas complexas e diferem uma da outra, sugiro que você use modelos de vista separados para cada uma.Espero que isso esclareça qualquer confusão que você tenha sobre os modelos de exibição e domínio.
fonte
O modelo de exibição é uma classe que representa o modelo de dados usado em uma exibição específica. Poderíamos usar esta classe como modelo para uma página de login:
Usando este modelo de vista, você pode definir a vista (mecanismo de vista Razor):
E ações:
O que produz esse resultado (a tela é obtida após o envio do formulário, com mensagens de validação):
Como você pode ver, um modelo de exibição tem muitas funções:
LabelFor
,EditorFor
,DisplayFor
ajudantes).Outro exemplo de um modelo de visualização e sua recuperação: queremos exibir dados básicos do usuário, seus privilégios e nome de usuário. Criamos um modelo de vista especial, que contém apenas os campos obrigatórios. Recuperamos dados de diferentes entidades do banco de dados, mas a visualização apenas reconhece a classe do modelo de visualização:
Recuperação:
fonte
Editar: atualizei esta resposta no meu blog:
http://www.samwheat.com/post/The-function-of-ViewModels-in-MVC-web-development
Minha resposta é um pouco longa, mas acho importante comparar modelos de exibição com outros tipos de modelos comumente usados para entender por que eles são diferentes e por que são necessários.
Para resumir e responder diretamente à pergunta que é feita:
De um modo geral, um modelo de vista é um objeto que contém todas as propriedades e métodos necessários para renderizar uma vista. As propriedades do modelo de exibição geralmente estão relacionadas a objetos de dados, como clientes e pedidos, e também contêm propriedades relacionadas à página ou ao próprio aplicativo, como nome de usuário, nome do aplicativo etc. crie uma página html. Uma das muitas razões para usar um modelo de exibição é que os modelos de exibição fornecem uma maneira de testar unidades determinadas tarefas de apresentação, como lidar com a entrada do usuário, validar dados, recuperar dados para exibição etc.
Aqui está uma comparação dos modelos de entidade (modelos a.ka. do DTO), modelos de apresentação e modelos de exibição.
Objetos de transferência de dados, também conhecidos como "Modelo"
Um Data Transfer Object (DTO) é uma classe com propriedades que correspondem a um esquema de tabela em um banco de dados. Os DTOs são nomeados por seu uso comum na transferência de dados de e para um repositório de dados.
Características dos DTOs:
• São objetos de negócios - sua definição depende dos dados do aplicativo.
• Normalmente contêm apenas propriedades - sem código.
• Usado principalmente para transportar dados de e para um banco de dados.
• As propriedades correspondem exatamente ou estreitamente aos campos em uma tabela específica em um armazenamento de dados.
As tabelas do banco de dados geralmente são normalizadas, portanto, os DTOs também são normalmente normalizados. Isso os torna de uso limitado para apresentação de dados. No entanto, para certas estruturas de dados simples, elas costumam se sair muito bem.
Aqui estão dois exemplos de como os DTOs podem se parecer:
Modelos de Apresentação
Um modelo de apresentação é uma classe de utilitário usada para renderizar dados em uma tela ou relatório. Os modelos de apresentação geralmente são usados para modelar estruturas de dados complexas compostas de dados de vários DTOs. Os modelos de apresentação geralmente representam uma visão desnormalizada dos dados.
Características dos modelos de apresentação:
• São objetos de negócios - sua definição depende dos dados do aplicativo.
• Contêm principalmente propriedades. O código normalmente está limitado à formatação de dados ou à conversão de ou para um DTO. Os modelos de apresentação não devem conter lógica de negócios.
• Muitas vezes, apresentam uma visão desnormalizada dos dados. Ou seja, eles geralmente combinam propriedades de vários DTOs.
• Muitas vezes, contêm propriedades de um tipo de base diferente de um DTO. Por exemplo, os valores em dólares podem ser representados como cadeias de caracteres, para que possam conter vírgulas e um símbolo de moeda.
• Frequentemente definido por como eles são usados, bem como por suas características de objeto. Em outras palavras, um DTO simples que é usado como modelo de apoio para renderizar uma grade também é de fato um modelo de apresentação no contexto dessa grade.
Os modelos de apresentação são usados "conforme necessário" e "onde necessário" (enquanto os DTOs geralmente estão vinculados ao esquema do banco de dados). Um modelo de apresentação pode ser usado para modelar dados para uma página inteira, uma grade em uma página ou uma lista suspensa em uma grade em uma página. Os modelos de apresentação geralmente contêm propriedades que são outros modelos de apresentação. Os modelos de apresentação são geralmente construídos para uma finalidade de uso único, como para renderizar uma grade específica em uma única página.
Um modelo de apresentação de exemplo:
Ver modelos
Um modelo de vista é semelhante a um modelo de apresentação, pois é uma classe de suporte para renderizar uma vista. No entanto, é muito diferente de um modelo de apresentação ou de um DTO na forma como ele é construído. Os modelos de exibição geralmente contêm as mesmas propriedades que os modelos de apresentação e os DTOs e, por esse motivo, geralmente são confundidos um pelo outro.
Características dos modelos de exibição:
• A fonte única de dados é usada para renderizar uma página ou tela. Normalmente, isso significa que um modelo de exibição exporá todas as propriedades que qualquer controle na página precisará para se renderizar corretamente. Tornar o modelo de visualização a única fonte de dados para a visualização melhora muito sua capacidade e valor para testes de unidade.
• São objetos compostos que contêm propriedades que consistem em dados do aplicativo e propriedades usadas pelo código do aplicativo. Essa característica é crucial ao projetar o modelo de vista para reutilização e é discutida nos exemplos abaixo.
• Contenha o código do aplicativo. Os modelos de exibição geralmente contêm métodos chamados durante a renderização e quando o usuário está interagindo com a página. Esse código geralmente se refere à manipulação de eventos, animação, visibilidade de controles, estilo etc.
• Contenha o código que chama os serviços comerciais com a finalidade de recuperar dados ou enviá-los para um servidor de banco de dados. Esse código geralmente é colocado por engano em um controlador. A chamada de serviços de negócios de um controlador geralmente limita a utilidade do modelo de exibição para testes de unidade. Para ser claro, os próprios modelos de exibição não devem conter lógica de negócios, mas devem fazer chamadas para serviços que contenham lógica de negócios.
• Muitas vezes, contêm propriedades que são outros modelos de exibição para outras páginas ou telas.
• São escritos "por página" ou "por tela". Um modelo de exibição exclusivo geralmente é escrito para todas as páginas ou telas de um aplicativo.
• Geralmente, derivam de uma classe base, já que a maioria das páginas e telas compartilha propriedades comuns.
Exibir composição do modelo
Conforme declarado anteriormente, os modelos de exibição são objetos compostos, pois combinam propriedades de aplicativos e dados de negócios em um único objeto. Exemplos de propriedades de aplicativos comumente usadas nos modelos de exibição são:
• Propriedades usadas para exibir o estado do aplicativo, como mensagens de erro, nome de usuário, status etc.
• Propriedades usadas para formatar, exibir, estilizar ou animar controles.
• Propriedades usadas para ligação de dados, como objetos de lista e propriedades que mantêm dados intermediários que são inseridos pelo usuário.
Os exemplos a seguir mostram por que a natureza composta dos modelos de vista é importante e como podemos construir melhor um Modelo de Vista que seja eficiente e reutilizável.
Suponha que estamos escrevendo um aplicativo da web. Um dos requisitos do design do aplicativo é que o título da página, o nome do usuário e o nome do aplicativo sejam exibidos em todas as páginas. Se queremos criar uma página para exibir um objeto de ordem de apresentação, podemos modificar o modelo de apresentação da seguinte maneira:
Esse design pode funcionar ... mas e se quisermos criar uma página que exibirá uma lista de pedidos? As propriedades PageTitle, UserName e ApplicationName serão repetidas e se tornarão difíceis de trabalhar. Além disso, e se quisermos definir alguma lógica no nível da página no construtor da classe? Não podemos mais fazer isso se criarmos uma instância para cada pedido que será exibido.
Composição sobre herança
Aqui está uma maneira de refazer o modelo de apresentação de pedidos, de forma que ele se torne um modelo de exibição real e seja útil para exibir um único objeto PresentationOrder ou uma coleção de objetos PresentationOrder:
Observando as duas classes acima, podemos ver que uma maneira de pensar em um modelo de exibição é que ele é um modelo de apresentação que contém outro modelo de apresentação como uma propriedade. O modelo de apresentação de nível superior (ou seja, modelo de exibição) contém propriedades relevantes para a página ou aplicativo, enquanto o modelo de apresentação (propriedade) contém propriedades relevantes para os dados do aplicativo.
Podemos dar um passo adiante em nosso design e criar uma classe de modelo de vista de base que pode ser usada não apenas para PresentationOrders, mas também para qualquer outra classe:
Agora podemos simplificar nosso PresentationOrderVM assim:
Podemos tornar nosso BaseViewModel ainda mais reutilizável, tornando-o genérico:
Agora, nossas implementações são fáceis:
fonte
MyViewModel<MyPresModel>
Se você possui propriedades específicas para a exibição e não relacionadas ao armazenamento de banco de dados / serviço / dados, é uma boa prática usar o ViewModels. Digamos, você deseja deixar uma caixa de seleção marcada com base em um campo do banco de dados (ou dois), mas o próprio campo do banco de dados não é um booleano. Embora seja possível criar essas propriedades no próprio Modelo e mantê-las ocultas da ligação aos dados, você pode não querer desorganizar o Modelo, dependendo da quantidade desses campos e transações.
Se houver muito poucos dados e / ou transformações específicas da visualização, você poderá usar o próprio Modelo
fonte
Não li todas as postagens, mas todas as respostas parecem estar faltando um conceito que realmente me ajudou a "entender" ...
Se um Modelo é semelhante a uma Tabela de banco de dados , um ViewModel é semelhante a uma Visualização de banco de dados - Uma visualização geralmente retorna pequenas quantidades de dados de uma tabela ou conjuntos complexos de dados de várias tabelas (junções).
Encontro-me usando o ViewModels para passar informações para um modo de exibição / formulário e, em seguida, transferindo esses dados para um modelo válido quando o formulário é enviado de volta ao controlador - também muito útil para armazenar Lists (IEnumerable).
fonte
O MVC não possui um modelo de visualização: possui um modelo, visualização e controlador. Um viewmodel faz parte do MVVM (Model-View-Viewmodel). O MVVM é derivado do Modelo de Apresentação e é popularizado no WPF. Também deve haver um modelo no MVVM, mas a maioria das pessoas perde completamente o ponto desse padrão e elas terão apenas uma visualização e um modelo de visualização. O modelo no MVC é semelhante ao modelo no MVVM.
No MVC, o processo é dividido em três responsabilidades diferentes:
O MVC não é muito adequado para aplicativos da web. É um padrão introduzido pelo Smalltalk para criar aplicativos de desktop. Um ambiente da web se comporta completamente diferente. Não faz muito sentido copiar um conceito de 40 anos do desenvolvimento da área de trabalho e colá-lo em um ambiente da Web. No entanto, muitas pessoas pensam que isso é bom, porque seu aplicativo compila e retorna os valores corretos. Isso é, na minha opinião, insuficiente para declarar uma certa opção de design como ok.
Um exemplo de modelo em um aplicativo da web pode ser:
O controlador pode usá-lo assim:
Seus métodos de controle e seus modelos serão pequenos, facilmente testáveis e diretos.
fonte
O modelo de exibição a é uma classe simples que pode conter mais de uma propriedade de classe. Nós o usamos para herdar todas as propriedades necessárias, por exemplo, eu tenho duas classes Student e Subject
Agora, queremos exibir os registros Nome do aluno e Nome do sujeito na exibição (no MVC), mas não é possível adicionar mais de uma aula, como:
o código acima irá gerar um erro ...
Agora criamos uma classe e podemos atribuir qualquer nome a ela, mas esse formato "XyzViewModel" facilitará o entendimento. É um conceito de herança. Agora criamos uma terceira classe com o seguinte nome:
Agora usamos esse ViewModel no modo de exibição
Agora podemos acessar todas as propriedades de StudentViewModel e a classe herdada no View.
fonte
Muitos exemplos grandes, deixe-me explicar de maneira clara e crocante.
ViewModel = Modelo criado para servir a vista.
A exibição do ASP.NET MVC não pode ter mais de um modelo; portanto, se precisarmos exibir propriedades de mais de um modelo na exibição, isso não será possível. O ViewModel serve a esse propósito.
View Model é uma classe de modelo que pode conter apenas as propriedades necessárias para uma visualização. Ele também pode conter propriedades de mais de uma entidade (tabelas) do banco de dados. Como o nome sugere, este modelo é criado específico para os requisitos de exibição.
Alguns exemplos de modelos de exibição estão abaixo
O ViewModel também pode ser usado para inserir e atualizar registros em mais de uma entidade. No entanto, o principal uso do ViewModel é exibir colunas de várias entidades (modelo) em uma única exibição.
A maneira de criar o ViewModel é a mesma que criar o Model, a maneira de criar a visualização para o Viewmodel é a mesma que criar a visualização para o Model.
Aqui está um pequeno exemplo de dados da lista usando o ViewModel .
Espero que isso seja útil.
fonte
O ViewModel é uma solução alternativa que corrige a falta de jeito conceitual da estrutura MVC. Representa a quarta camada na arquitetura Model-View-Controller de 3 camadas. quando Model (modelo de domínio) não é apropriado, muito grande (maior que 2-3 campos) para a View, criamos um ViewModel menor para passá-lo à View.
fonte
Um modelo de vista é um modelo conceitual de dados. Seu uso é, por exemplo, obter um subconjunto ou combinar dados de tabelas diferentes.
Você pode querer apenas propriedades específicas, portanto, isso permite carregar apenas essas e não propriedades desnecessárias adicionais
fonte
Projetando o ViewModel
Apresentando o modelo de exibição na exibição
Trabalhando com ação
fonte
View Model é a classe que podemos usar para renderizar dados no View. Suponha que você tenha duas entidades Place e PlaceCategory e deseje acessar os dados de ambas as entidades usando um único modelo; em seguida, usamos o ViewModel.
Portanto, no exemplo acima, Place e Category são as duas entidades diferentes e o PlaceCategory viewmodel é o ViewModel que podemos usar no View.
fonte
Se você deseja estudar o código de como configurar um aplicativo da Web "Linha de base" com o ViewModels, aconselho o download desse código no GitHub: https://github.com/ajsaulsberry/BlipAjax . Eu desenvolvi grandes aplicativos corporativos. Quando você faz isso, é problemático configurar uma boa arquitetura que lida com toda essa funcionalidade "ViewModel". Eu acho que com o BlipAjax você terá uma "linha de base" muito boa para começar. É apenas um site simples, mas excelente em sua simplicidade. Gosto da maneira como eles usaram o idioma inglês para apontar o que é realmente necessário no aplicativo.
fonte