ASP .NET - Trabalhando com Dynamic Data Controls
Hoje vamos abordar como usar ASP .NET e trabalhar com Dynamic Data Controls.(DDC)
Esse recurso foi introduzido no ASP.NET 3.5 SP1. Ele simplifica a tarefa da entrada de dados usando o os modelos do Entity Framework ou LINQ to SQL para gerar automaticamente todas as máscaras usadas para exibir, alterar ou inserir dados. O Controle dinâmico de dados são uma nova onda de controles declarativos que permitem desenvolver aplicações de dados simples de forma rápida.
Muitas aplicações são essencialmente orientada a dados, em vez de utilizar uma arquitetura n-camadas, os DDC manipulam diretamente os dados. A idéia por trás dos controles Dynamic Data é construir dinamicamente a view e as máscaras de edição, usando o ObjectContext do Entity Framework ou DataContext do LINQ to SQL. Para isso a ASP.NET 4.0 suporta os provedores personalizados usando o padrão de projeto Provider Model.
Se você precisa rapidamente compor uma área editável sobre seus objetos mapeados, os controles dinâmicos de dados são uma opção a considerar levando em conta a produtividade. Você pode literalmente construir uma área de administração para seus sites em segundos com os DDC.
Obs: Atente que este recurso é mais uma opção que a plataforma .NET lhe oferece e você pode decidir usá-lo ou não. Ele será útil em algumas situações e em outras será totalmente desaconselhável usar o recurso. De qualquer forma creio que você deva conhecer mais esta opção.
O Visual Studio 2010 e o Visual Web Developer 2010 Express Edition contém dois modelos voltados especificamente para os controles de dados dinâmicos. Cabe a você escolher o mais apropriado ao seu caso, dependendo se você usar o LINQ to SQL ou Entity Framework. Se você pode decidir querer construir seu próprio provedor, tudo bem, na versão 4.0 você tem suporte para este caminho.
Os controles dinâmicos de dados são um grupo de controles que aproveitam algumas das características mais interessantes da nova ASP.NET 4.0 como o roteamento de URLs e o query extender (extensor de consulta).
Usando os Dynamic Data Controls na prática
Na parte prática eu vou usar como ferramenta o Visual Web Developer 2010 Express Edition que é grátis mas se quiser pode usar o Visual Studio 2010.
Como mencionei podemos utilizar os DDC usando o Entity Framework ou o Linq to SQL. Nesta prática eu vou usar o Entity Framework 4.1 e a linguagem Visual Basic.
Abra o Visual Web Developer 2010 Express Edition e no menu File clique em New Project;
A seguir selecione os templates Visual Basic -> Web -> ASP .NET Dynamic Data Entities Web Application e informe o nome AspNet_DDC para a aplicação clicando no botão OK;
Observe que temos duas opções para usar os Dynamic Data Controls e escolhemos a que usando Entity Framework;
Uma aplicação típica dos controles dinâmicos de dados esta baseada nos seguintes conceitos:
- Cada MetaTable está dentro de um
MetaModel, que detém todas as informações sobre as tabelas;
- Cada MetaTable contém informações sobre as colunas,
representada por um instância de MetaColumn;
- Esta informação é registrada em tempo de execução,
geralmente usando o método RegisterContext do MetaModel;
- Por padrão, todas as tabelas e as colunas são visíveis, mas
podemos alterar isso;
A estrutura da solução gerada pode ser vista na janela Solution Explorer :
Note que toda a estrutura
das pastas contendo as páginas já esta pronta Para ativar o recurso basta gerar o
modelo de dados e informar o nome do |
Não é obrigatório o registro do modelo no global.asax, mas esse é o comportamento padrão. Assim você tem que registrar o modelo na inicialização, e o arquivo Global.asax é a opção padrão para fazer isso.
Após criar o projeto se você abrir o arquivo Global.asax você verá o código semelhante ao mostrado a seguir:
Imports System.Web.Routing Imports System.Web.DynamicData Public Class Global_asax Inherits HttpApplication Private Shared s_defaultModel As New MetaModel Public Shared ReadOnly Property DefaultModel() As MetaModel Get Return s_defaultModel End Get End Property Public Shared Sub RegisterRoutes(ByVal routes As RouteCollection) ' IMPORTANT: DATA MODEL REGISTRATION ' Uncomment this line to register an ADO.NET Entity Framework model for ASP.NET Dynamic Data. ' Set ScaffoldAllTables = true only if you are sure that you want all tables in the ' data model to support a scaffold (i.e. templates) view. To control scaffolding for ' individual tables, create a partial class for the table and apply the ' <ScaffoldTable(true)> attribute to the partial class. ' Note: Make sure that you change "YourDataContextType" to the name of the data context ' class in your application. ' DefaultModel.RegisterContext(GetType(YourDataContextType), New ContextConfiguration() With {.ScaffoldAllTables = False}) ' The following statement supports separate-page mode, where the List, Detail, Insert, and ' Update tasks are performed by using separate pages. To enable this mode, uncomment the following ' route definition, and comment out the route definitions in the combined-page mode section that follows. routes.Add(New DynamicDataRoute("{table}/{action}.aspx") With { .Constraints = New RouteValueDictionary(New With {.Action = "List|Details|Edit|Insert"}), .Model = DefaultModel}) ' The following statements support combined-page mode, where the List, Detail, Insert, and ' Update tasks are performed by using the same page. To enable this mode, uncomment the ' following routes and comment out the route definition in the separate-page mode section above. 'routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { ' .Action = PageAction.List, ' .ViewName = "ListDetails", ' .Model = DefaultModel}) 'routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { ' .Action = PageAction.Details, ' .ViewName = "ListDetails", ' .Model = DefaultModel}) End Sub Private Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) RegisterRoutes(RouteTable.Routes) End Sub End Class |
Neste exemplo, estamos usando Entity Framework, mas com o LINQ to SQL tanto o código como os conceitos são idênticos. A propriedade ScaffoldAllTables é importante porque, por padrão o seu valor é false. Definindo-a como true, você vai automaticamente mostrar todas as tabelas na primeira página.
Quando você cria um novo aplicativo com base neste projeto, você vai perceber que todo o código já está pronto, e você não precisa escrevê-lo! Uma nova rota também já esta registrada:
routes.Add(New DynamicDataRoute("{table}/{action}.aspx") With { .Constraints = New RouteValueDictionary(New With {.Action = "List|Details|Edit|Insert"}),.Model = DefaultModel}) |
Observe que o código gerado esta comentado e devemos informar o nome do nosso contexto de dados gerado usando o Entity Framework.
Vamos então gerar um modelo de entidades usando como exemplo o banco de dados Northwind.mdf.
No menu Project clique em Add New Item;
A seguir clique no template Data -> ADO .NET Entity Data Model e informe o nome Northwind.edmx e clique em Add;
Na próxima janela do assistente escolha a opção : Generate from database e clique em Next>;
A seguir escolha a conexão com o banco de dados Northwind.mdf e clique em Next>
A seguir selecione as tabelas Categories, Customers, Orders, Orders Details e Products e clique em Finish;
O modelo gerado pode ser visto na figura abaixo. O nome do contexto é NorthwindEntities.
Vamos agora descomentar o código do arquivo Global.asax e informar o nome do contexto gerado. O código deverá ficar conforme abaixo:
Imports System.Web.Routing Imports System.Web.DynamicData Public Class Global_asax Inherits HttpApplication Private Shared s_defaultModel As New MetaModel Public Shared ReadOnly Property DefaultModel() As MetaModel Get Return s_defaultModel End Get End Property Public Shared Sub RegisterRoutes(ByVal routes As RouteCollection) ' IMPORTANT: DATA MODEL REGISTRATION ' Uncomment this line to register an ADO.NET Entity Framework model for ASP.NET Dynamic Data. ' Set ScaffoldAllTables = true only if you are sure that you want all tables in the ' data model to support a scaffold (i.e. templates) view. To control scaffolding for ' individual tables, create a partial class for the table and apply the ' <ScaffoldTable(true)> attribute to the partial class. ' Note: Make sure that you change "YourDataContextType" to the name of the data context ' class in your application. DefaultModel.RegisterContext(GetType(NorthwindEntities), New ContextConfiguration() With {.ScaffoldAllTables = True}) ' The following statement supports separate-page mode, where the List, Detail, Insert, and ' Update tasks are performed by using separate pages. To enable this mode, uncomment the following ' route definition, and comment out the route definitions in the combined-page mode section that follows. routes.Add(New DynamicDataRoute("{table}/{action}.aspx") With { .Constraints = New RouteValueDictionary(New With {.Action = "List|Details|Edit|Insert"}), .Model = DefaultModel}) ' The following statements support combined-page mode, where the List, Detail, Insert, and ' Update tasks are performed by using the same page. To enable this mode, uncomment the ' following routes and comment out the route definition in the separate-page mode section above. routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { .Action = PageAction.List, .ViewName = "ListDetails", .Model = DefaultModel}) routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { .Action = PageAction.Details, .ViewName = "ListDetails", .Model = DefaultModel}) End Sub Private Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) RegisterRoutes(RouteTable.Routes) End Sub End Class |
O código destacado em azul foi descomentado e o nosso contexto foi incluído na linha de código abaixo:
DefaultModel.RegisterContext(GetType(NorthwindEntities), New ContextConfiguration() With {.ScaffoldAllTables = True})
Como definimos a propriedade ScaffoldAllTables como True veremos todas as tabelas na primeira página.
E com isso terminamos o nosso trabalho (que trabalhão hein !!!). Vamos agora testar e verificar o resultado.
Executando o projeto iremos obter:
Na primeira página visualizamos todas as tabelas do modelo gerado:
Clicando na tabela Categories obtemos a seguinte página:
Clicando no link View Products obtemos:
Note que todas as opções para editar, deletar, visualizar, filtrar e paginar os dados das tabelas já estão disponíveis.
- Do ponto de vista
técnico, os modelos das página são definidos na pasta: DynamicData/PageTemplates;
- A mágica é executada por um controle especial: o DynamicControl,
que trabalha com os controles GridView e DetailsView para
exibir campos dinamicamente;
- Esses controles foram adaptados para trabalhar facilmente com
esses novos recursos fornecidos por dados dinâmicos. Você
também pode usar outros controles, como ListView ou FormView,
utilizando a mesma abordagem;
- O controle DynamicControl trabalha com a
informação chamada metadata;
- Você pode usar os recursos da anotações de dados do
namespace System.ComponentModel.DataAnnonations
para decorar as classes e para fornecer informações; adicionais
que os DDC podem ler para entender como uma coluna é composta,
qual o tipo que possui, e assim por diante;
- Graças às anotações de dados (Data Annotations),
os DDC fornecem automaticamente a validação do formulário, com
base nos metadados disponíveis;
- A renderização está associada a controles específicos,
dependendo do tipo de dados;
Dessa forma os Controles Dinâmicos de Dados apresentam uma tecnologia poderosa que simplifica a entrada de dados, onde a sua estratégia de dados coincide com o seu modelo mapeado.
E você pode estender ainda mais esse comportamento mas isso é assunto para outro artigo.
Pegue o projeto completo aqui: AspNet_DDC.zip
"Vigiai pois, porque não sabeis o dia nem a hora em que o Filho do homem há de vir." Mateus 25:13
Referências: