JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Cómo incorporar Dynamic Data a un proyecto Web existente

El pasado lunes, en la charla on-line que impartí para el NEt User Group de la UOC sobre Dynamic Data, comenté que existía la posibilidad de sacarle partido a esta interesante tecnología sin tener que crear desde cero un proyecto especial de Dynamic Data, es decir, sin partir de este diálogo:

Tal y como prometí ese día, a continuación explico cómo añadir las capacidades de Dynamic Data a un proyecto Web pre-existente. Como veremos se trata de algo muy sencillo.

Dado que Dynamic Data se basa en el uso plantillas, tanto para las acciones como para generar campos, entidades concretas y otros controles, lo primero que debemos hacer es copiar desde un proyecto Dynamic Data pre-existente los siguientes elementos:

1.- La carpeta de nombre DynamicData
2.- La página maestra Site.master y su correspondiente archivo de código Site.master.vb (o.cs si trabajamos con C#)
3.- La hoja de estilos Site.css

Usa el propio explorador de archivos de Windows para copiarlos, y luego refresca la lista de archivos de proyecto con el botón correspondiente en el explorador de proyectos:

Con esto sólo no es suficiente, ya que también debemos declarar al menos un modelo de datos con el que trabajar.

Asumiendo que hemos definido un contexto de acceso a datos con Linq2SQL o con Entity Framework (enla figura anterior tenemos uno definido en App_Code, con el nombre "MiModelo.dbml"), lo que tenemos que hacer es declararlo en Global.asax a la hora de arrancar la aplicación. Así, debemos escribir en el evento Application_Start un código análogo al siguiente:

    Sub Application_Start(ByVal sender As Object, _
            ByVal e As EventArgs)
        Dim DefaultModel As MetaModel = New MetaModel()
        DefaultModel.RegisterContext(GetType(MiModeloDataContext), _
                New ContextConfiguration() With {.ScaffoldAllTables = True})
    End Sub

Además, debemos asegurarnos de que están incluídos los siguientes espacios de nombres:

<%@ Import Namespace="System.ComponentModel.DataAnnotations" %>
<%@ Import Namespace="System.Web.Routing" %>
<%@ Import Namespace="System.Web.DynamicData" %>

De esta manera, ya tenemos todo lo necesario para poder usar DynamicData junto con controles de acceso a datos en páginas propias. Más sobre esto enseguida.

Antes de continar me gustaría indicar que podemos hacer uso de las rutas de acceso dinámico a acciones con tablas simplemente declarándolas de la manera habitual, es decir, con un código similar al siguiente dentro de Application_Start en Global.asax:

    RouteTable.Routes.Add(New DynamicDataRoute( _ 
        "{table}/{action}.aspx") _
        With {.Constraints = New RouteValueDictionary( _
        New With {Key .Action = "List|Details|Edit|Insert"}), _
        .Model = DefaultModel})

de forma que quedaría un evento con el código de esta figura:

A partir de este momento podríamos manejar cualquier tabla de nuestro modelo de datos con tan sólo escribir una ruta del estilo de esta:

http://miapplicacion/Productos/List

para listar todos los productos de la base de datos y poder editarlos, borrarlos o añadir nuevos. O también:

http://miapplicacion/Clientes/Insert

para insertar un nuevo cliente en la tabla Clientes (si la hubiera). Como vemos muy útil...

Páginas propias con Dynamic Data

Además de lo que acabamos de ver, que genera páginas de mantenimiento con rutas pre-establecidas, podemos sacar partido a Dynamic Data en formularios propios usando controles normales de datos, como una rejilla (GrtidView) o un FormView, usando los controles especiales disponibles a tal efecto:

Por ejemplo, añade una nueva página y en ésta agrega un control DynamicDataManager (figura anterior), y desde el grupo de controles de datos un LinqDataSource o EntityDataSource (según la tecnología que hayas usado para el modelo de datos),  y una rejilla GridView.

En la vista de marcado de la página .aspx edita el control DynamicDataManager para que active esta tecnología en la rejilla, con un código como este:

        <asp:DynamicDataManager ID="DynamicDataManager1" runat="server" >
            <DataControls>
                 <asp:DataControlReference ControlID="GridView1" />
            </DataControls>
        </asp:DynamicDataManager>

Con esto lo que conseguimos es qu el control GridView1 sea capaz de generar automáticamente campos para mostrar y editar campos de la base de datos que se correspondan con el modelo de datos. Es decir, estamos habilitando Dynamic Data en ese control.

En el control LinqDataSource se configura el contexto de datos que representa a nuestro modelo para que utilice una de las tablas que nos interese (por ejemplo la de productos). Asignamos el control DataSource a la rejilla pero deshabilitamos la capacidad de ésta para generar los campos de manera automática.

Ahora sólo nos resta añadir campos dinámicos a la rejilla de forma que, en tiempo de ejecución, éstos se muestren de acuerdo con lo especificado en el modelo de datos (validación, formato, etc... gracias a las DataAnnotations) y en las plantillas para campos, tal y como se hace siempre en Dynamic Data. Para ello existe un nuevo tipo de campo llamado DynamicField que se usa precisamente para esto. Sólo tenemos que indicar el nombre del campo en el modelo que queremos enlazar y listo, ofreciéndosenos ayuda con Intellisense en Visual Studio:

Quedando campos con el siguiente aspecto:

pudiendo asignar otras características como el texto para la cabecera o el formato (si bien este último es más interesante asignarlo mediante metadatos en el modelo, ya que así nos aseguramos un uso consistente en toda la aplicación).

Si no queremos añadirlos a mano Visual Studio nos ofrece un pequeño asistente desde la lista de acciones de la rejilla:

lo que es mucho más cómodo. Podemos añadirle además un DynamicValidator a la página (ver grupo de controles de dynamic data en una figura anterior), asociándolo con el a rejilla. Con esto tenemos controlada la validación de cada uno de los campos dinámicos que editemos dentro de la rejilla.

Ahora, cuando ejecutemos esta página, dentro de la rejilla se mostrarán los campos de acuerdo con el modelo de datos, y tendremos automáticamente los controles de edición más apropiados según el tipo de datos y el modelo, validación de la información introducida, etc... con las ventajas de velocidad y robustez que ello conlleva.

Espero que esto os resulte útil (sobre todo a los que asistísteis el otro día a mi ponencia sobre Dynamic Data, jeje) :-)

José Manuel Alarcón
Banner

Comentarios (4) -

El programa compila sin embargo me manda el error intentando acceder a la tabla Facturacion_ComplementoPoliza:

The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

Requested URL: /Facturacion_ComplementoPoliza/List.aspx


--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272

Hay manera de ir comprobando las piezas ensambladas en tu explicación,
tienes ejemplo de código funcionando, muchas gracias saludos.

Responder

Resuelto: al hacer referencia a la tabla hay que agregar una s (referencia el plural) Facturacion_ComplementoPolizas.

Responder

Resuelto: al hacer referencia a la tabla hay que agregar una s (referencia el plural) Facturacion_ComplementoPolizas.

Responder

Hola, tengo una duda y no se como resolverla. Me encontré con una pagina montada con dynamicdata y al migrarla de server me da error en global.asax porque no encuentra el modelo de datos. He copiado todos los directorios y paginas. ¿Que debo hacer para que lo reconozca? Intento compilar la solución(proyecto, que no da error) y sigue sin reconocerlo.

model.RegisterContext(GetType(aqui_el_nombrede_del_molo_que_habia), New ContextConfiguration() With {.ScaffoldAllTables = True})


Gracias y saludos cordiales

Responder

Agregar comentario