Visualizar datos con ObjectDataSource (C#)

por Scott Mitchell

Descargar PDF

En este tutorial se examina el control ObjectDataSource. Mediante este control puede enlazar datos recuperados del BLL creado en el tutorial anterior sin tener que escribir una línea de código.

Introducción

Con la arquitectura de la aplicación y el diseño de página del sitio web completos, estamos listos para empezar a explorar cómo realizar una variedad de tareas comunes relacionadas con los datos y los informes. En los tutoriales anteriores hemos visto cómo enlazar datos desde DAL y BLL mediante programación a un control web de datos en una página ASP.NET. Esta sintaxis que asigna la propiedad DataSource del control web de datos a los datos que se van a mostrar y, a continuación, llamar al método DataBind() del control era el patrón usado en aplicaciones de ASP.NET 1.x y puede seguir usándose en las aplicaciones 2.0. Sin embargo, los nuevos controles de origen de datos de ASP.NET 2.0 ofrecen una manera declarativa de trabajar con datos. Con estos controles puede enlazar datos recuperados del BLL creado en el tutorial anterior sin tener que escribir una línea de código.

ASP.NET 2.0 incluye cinco controles de origen de datos integrados SqlDataSource, AccessDataSource, ObjectDataSource, XmlDataSourcey SiteMapDataSource aunque puede crear sus propios controles de origen de datos personalizados, si es necesario. Puesto que hemos desarrollado una arquitectura para nuestra aplicación de tutorial, usaremos ObjectDataSource en nuestras clases BLL.

ASP.NET 2.0 Includes Five Built-In Data Source Controls

Figura 1: ASP.NET 2.0 incluye cinco controles de origen de datos integrados

ObjectDataSource actúa como proxy para trabajar con algún otro objeto. Para configurar ObjectDataSource especificamos este objeto subyacente y cómo se asignan sus métodos a los métodos Select, Insert, Update y Delete de ObjectDataSource. Una vez especificado este objeto subyacente y sus métodos asignados a los de ObjectDataSource, podemos enlazar ObjectDataSource a un control web de datos. ASP.NET incluye muchos controles web de datos, como GridView, DetailsView, RadioButtonList y DropDownList, entre otros. Durante el ciclo de vida de la página, es posible que el control web de datos necesite tener acceso a los datos a los que está enlazado, lo que se realizará invocando el método Select de ObjectDataSource; si el control web de datos admite la inserción, actualización o eliminación, se pueden realizar llamadas a sus métodos, o a los métodos de ObjectDataSource Insert, Update, o Delete. A continuación, las llamadas se enrutan mediante ObjectDataSource a los métodos del objeto subyacente adecuados, como se muestra en el diagrama siguiente.

The ObjectDataSource Serves as a Proxy

Figura 2: ObjectDataSource actúa como proxy (Haga clic para ver la imagen de tamaño completo)

Aunque ObjectDataSource se puede usar para invocar métodos para insertar, actualizar o eliminar datos, vamos a centrarnos en devolver datos; los tutoriales futuros explorarán el uso de los controles de ObjectDataSource y web de datos que modifican los datos.

Paso 1: Agregar y configurar el control de ObjectDataSource

Para empezar, abra la página SimpleDisplay.aspx en la carpeta BasicReporting, cambie a la vista Diseño y, a continuación, arrastre un control ObjectDataSource desde el Cuadro de herramientas a la superficie de diseño de la página. ObjectDataSource aparece como un cuadro gris en la superficie de diseño porque no produce ningún marcado; simplemente accede a los datos invocando un método desde un objeto especificado. Los datos devueltos por un ObjectDataSource pueden mostrarse mediante un control web de datos, como GridView, DetailsView, FormView, etc.

Nota:

Como alternativa, primero puede agregar el control web de datos a la página y, a continuación, desde su etiqueta inteligente, elija la opción <Nuevo origen de datos> en la lista desplegable.

Para especificar el objeto subyacente de ObjectDataSource y cómo se asignan los métodos de ese objeto a ObjectDataSource, haga clic en el vínculo Configurar origen de datos desde la etiqueta inteligente de ObjectDataSource.

Click the Configure Data Source Link from the Smart Tag

Figura 3: Haga clic en el vínculo Configurar origen de datos desde la etiqueta inteligente (Haga clic para ver la imagen de tamaño completo)

Esto abre el Asistente para configurar orígenes de datos. En primer lugar, debemos especificar el objeto con el que va a trabajar el ObjectDataSource. Si la casilla "Mostrar solo componentes de datos" está activada, la lista desplegable de esta pantalla muestra solo los objetos que se han decorado con el atributo DataObject. Actualmente nuestra lista incluye TableAdapters en el Conjunto de datos con tipo y las clases BLL que creamos en el tutorial anterior. Si olvidó agregar el atributo DataObject a las clases de Capa lógica de negocios, no los verá en esta lista. En ese caso, desactive la casilla "Mostrar solo componentes de datos" para ver todos los objetos, que deben incluir las clases BLL (junto con las demás clases del Conjunto de datos con tipo DataSet, DataTables, DataRows, etc.).

En esta primera pantalla, elija la clase ProductsBLL en la lista desplegable y haga clic en Siguiente.

Specify the Object to Use with the ObjectDataSource Control

Figura 4: Especificar el objeto que se va a usar con el control de ObjectDataSource (Haga clic para ver la imagen de tamaño completo)

La siguiente pantalla del asistente le pide que seleccione el método que debe invocar ObjectDataSource. En la lista desplegable se enumeran los métodos que devuelven datos del objeto seleccionado en la pantalla anterior. Aquí vemos GetProductByProductID, GetProducts, GetProductsByCategoryIDy GetProductsBySupplierID. Seleccione el método GetProducts en la lista desplegable y haga clic en Finalizar (si agregó el DataObjectMethodAttribute a los métodos de ProductBLL como se muestra en el tutorial anterior, esta opción se seleccionará de forma predeterminada).

Choose the Method for Returning Data from the SELECT Tab

Figura 5: Elija el método para devolver datos en la pestaña SELECT (Haga clic para ver la imagen de tamaño completo)

Configurar ObjectDataSource manualmente

El Asistente para configurar orígenes de datos de ObjectDataSource ofrece una manera rápida de especificar el objeto que usa y para asociar los métodos del objeto que se invocan. Sin embargo, puede configurar ObjectDataSource a través de sus propiedades, ya sea a través de la ventana Propiedades o directamente en el marcado declarativo. Simplemente establezca la propiedad TypeName en el tipo del objeto subyacente que se va a usar y el SelectMethod en el método que se va a invocar al recuperar datos.

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

Incluso si prefiere el Asistente para configurar orígenes de datos, puede haber ocasiones en las que necesite configurar manualmente ObjectDataSource, ya que el asistente solo enumera las clases creadas por el desarrollador. Si desea enlazar ObjectDataSource a una clase de .NET Framework, como la clase Membership, para tener acceso a la información de la cuenta de usuario o la clase Directory para trabajar con la información del sistema de archivos, deberá establecer manualmente las propiedades de ObjectDataSource.

Paso 2: Agregar un control web de datos y enlazarlo al ObjectDataSource

Una vez que ObjectDataSource se ha agregado a la página y se ha configurado, estamos listos para agregar controles web de datos a la página para mostrar los datos devueltos por el método Select de ObjectDataSource. Cualquier control web de datos se puede enlazar a un ObjectDataSource; echemos un vistazo a la visualización de los datos de ObjectDataSource en GridView, DetailsView y FormView.

Enlace de GridView a ObjectDataSource

Agregue un control de GridView desde el Cuadro de herramientas a la superficie de diseño de SimpleDisplay.aspx. En la etiqueta inteligente de GridView, elija el control ObjectDataSource que hemos agregado en el paso 1. Esto creará automáticamente un BoundField en GridView para cada propiedad devuelta por los datos del método Select de ObjectDataSource (es decir, las propiedades definidas por el DataTable Products).

A GridView Has Been Added to the Page and Bound to the ObjectDataSource

Figura 6: Se ha agregado un control GridView a la página y enlazado a ObjectDataSource (Haga clic para ver la imagen de tamaño completo)

A continuación, puede personalizar, reorganizar o quitar los BoundFields de GridView haciendo clic en la opción Editar columnas de la etiqueta inteligente.

Manage the GridView's BoundFields Through the Edit Columns Dialog Box

Figura 7: Administrar los BoundFields de GridView a través del cuadro de diálogo Editar columnas (Haga clic para ver la imagen de tamaño completo)

Dedique un momento a modificar los BoundFields de GridView, quitando los BoundFields ProductID, SupplierID, CategoryID, QuantityPerUnit, UnitsInStock, UnitsOnOrder, y ReorderLevel. Simplemente seleccione BoundField en la lista de la parte inferior izquierda y haga clic en el botón eliminar (la X roja) para quitarlos. A continuación, reorganiza los BoundFields para que los BoundFields CategoryName y SupplierName precedan al BoundField UnitPrice seleccionando estos BoundFields y haciendo clic en la flecha hacia arriba. Establezca las propiedades HeaderText de los BoundFields restantes en Products, Category, Supplier y Price, respectivamente. A continuación, haga que el BoundField Price se formatee como moneda estableciendo la propiedad del BoundField HtmlEncode en False y su propiedad DataFormatString en {0:c}. Por último, alinee horizontalmente el Price a la derecha y la casilla Discontinued en el centro a través de la propiedad ItemStyle/HorizontalAlign.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName"
         HeaderText="Product" SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName"
          HeaderText="Category" ReadOnly="True"
          SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
          HeaderText="Supplier" ReadOnly="True"
          SortExpression="SupplierName" />
        <asp:BoundField DataField="UnitPrice"
          DataFormatString="{0:c}" HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
        <asp:CheckBoxField DataField="Discontinued"
          HeaderText="Discontinued" SortExpression="Discontinued">
            <ItemStyle HorizontalAlign="Center" />
        </asp:CheckBoxField>
    </Columns>
</asp:GridView>

The GridView's BoundFields Have Been Customized

Figura 8: Se han personalizado los BoundFields de GridView (Haga clic para ver la imagen de tamaño completo)

Uso de temas para un aspecto coherente

Estos tutoriales se esfuerzan por quitar cualquier configuración de estilo de nivel de control, utilizando en su lugar hojas de estilos en cascada definidas en un archivo externo siempre que sea posible. El archivo Styles.css contiene las clases CSS DataWebControlStyle, HeaderStyle, RowStyle y AlternatingRowStyle que se deben usar para dictar la apariencia de los controles web de datos usados en estos tutoriales. Para ello, podríamos establecer la propiedad CssClass de GridView en DataWebControlStyle, y sus propiedades HeaderStyle, RowStyle y AlternatingRowStyle de CssClass en consecuencia.

Si establecemos estas propiedades de CssClass en el control web, tendríamos que recordar establecer explícitamente estos valores de propiedad para cada control web de datos agregado a nuestros tutoriales. Un enfoque más fácil de administrar es definir las propiedades predeterminadas relacionadas con CSS para los controles GridView, DetailsView y FormView mediante un tema. Un tema es una colección de configuraciones de propiedades de nivel de control, imágenes y clases CSS que se pueden aplicar a las páginas de un sitio para aplicar una apariencia común.

Nuestro tema no incluirá imágenes ni archivos CSS (dejaremos la hoja de estilos Styles.css tal como está, definida en la carpeta raíz de la aplicación web), pero incluiremos dos máscaras. Una máscara es un archivo que define las propiedades predeterminadas de un control web. En concreto, tendremos un archivo de máscara para los controles GridView y DetailsView, que indican las propiedades predeterminadas relacionadas con CssClass.

Empiece agregando un nuevo archivo de máscara al proyecto denominado GridView.skin haciendo clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones y seleccionando Agregar nuevo elemento.

Add a Skin File Named GridView.skin

Figura 9: Agregar un archivo de máscara denominado GridView.skin (Haga clic para ver la imagen de tamaño completo)

Los archivos de máscara deben colocarse en un tema, que se encuentran en la carpeta App_Themes. Dado que aún no tenemos una carpeta de este tipo, Visual Studio le ofrecerá crear una para nosotros al agregar nuestra primera máscara. Haga clic en Sí para crear la carpeta App_Theme y colocar allí el nuevo archivo GridView.skin.

Let Visual Studio Create the App_Theme Folder

Figura 10: Permitir que Visual Studio cree la carpeta App_Theme (Haga clic para ver la imagen de tamaño completo)

Esto creará un nuevo tema en la carpeta App_Themes denominada GridView con el archivo de máscara GridView.skin.

The GridView Theme has Been Added to the App_Theme Folder

Figura 11: Se ha agregado el tema GridView a la carpeta App_Theme

Cambie el nombre del tema GridView a DataWebControls (haga clic con el botón derecho en la carpeta GridView de la carpeta App_Theme y elija Cambiar nombre). A continuación, escriba el marcado siguiente en el archivo GridView.skin :

<asp:GridView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
</asp:GridView>

Esto define las propiedades predeterminadas de las propiedades relacionadas con la CssClass para cualquier GridView en cualquier página que use el tema DataWebControls. Vamos a agregar otra máscara para DetailsView, un control web de datos que usaremos en breve. Agregue una nueva máscara al tema DataWebControls denominada DetailsView.skin y agregue el marcado siguiente:

<asp:DetailsView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <FieldHeaderStyle CssClass="HeaderStyle" />
</asp:DetailsView>

Con nuestro tema definido, el último paso es aplicar el tema a nuestra página ASP.NET. Un tema se puede aplicar página por página o para todas las páginas de un sitio web. Vamos a usar este tema para todas las páginas del sitio web. Para ello, agregue el marcado siguiente a Web.config en la sección <system.web>:

<pages styleSheetTheme="DataWebControls" />

Eso es todo. La configuración de styleSheetTheme indica que las propiedades especificadas en el tema no deben invalidar las propiedades especificadas en el nivel de control. Para especificar que la configuración del tema debe superar la configuración del control, use el atributo theme en lugar de styleSheetTheme. Desafortunadamente, la configuración del tema especificada a través del atributo theme no aparece en la vista Diseño de Visual Studio. Consulte Temas de ASP.NET y máscaras de información general y Usar temas de estilos del lado del servidor para obtener más información sobre temas y máscaras; consulte Cómo aplicar temas de ASP.NET para obtener más información sobre cómo configurar una página para usar un tema.

The GridView Displays the Product's Name, Category, Supplier, Price, and Discontinued Information

Figura 12: GridView muestra el nombre del producto, la categoría, el proveedor, el precio y la información interrumpida (Haga clic para ver la imagen de tamaño completo)

Mostrar un registro a la vez en DetailsView

GridView muestra una fila para cada registro devuelto por el control de origen de datos al que está enlazado. Sin embargo, hay ocasiones en las que es posible que deseemos mostrar un único registro o solo un registro a la vez. El control DetailsView ofrece esta funcionalidad, que se representa como un <table> HTML con dos columnas y una fila para cada columna o propiedad enlazada al control. Puede pensar en DetailsView como un GridView con un único registro girado en 90 grados.

Empiece agregando un control DetailsView encima del GridView en SimpleDisplay.aspx. A continuación, vincule al mismo control ObjectDataSource que GridView. Al igual que con GridView, se agregará un BoundField a DetailsView para cada propiedad del objeto devuelto por el método Select de ObjectDataSource. La única diferencia es que los BoundFields de DetailsView se diseñan horizontalmente en lugar de verticalmente.

Add a DetailsView to the Page and Bind it to the ObjectDataSource

Figura 13: Agregar una DetailsView a la página y enlazarla a ObjectDataSource (Haga clic para ver la imagen de tamaño completo)

Al igual que GridView, los BoundFields de DetailsView se pueden ajustar para proporcionar una visualización más personalizada de los datos devueltos por ObjectDataSource. En la Figura 14 se muestra DetailsView después de que sus propiedades BoundFields y CssClass se hayan configurado para que su apariencia sea similar al ejemplo de GridView.

The DetailsView Shows a Single Record

Figura 14: DetailsView muestra un único registro (Haga clic para ver la imagen de tamaño completo)

Tenga en cuenta que DetailsView solo muestra el primer registro devuelto por su origen de datos. Para permitir que el usuario recorra todos los registros, de uno en uno, debemos habilitar la paginación para DetailsView. Para ello, vuelva a Visual Studio y active la casilla Habilitar paginación en la etiqueta inteligente de DetailsView.

Enable Paging in the DetailsView Control

Figura 15: Habilitar paginación en el control DetailsView (Haga clic para ver la imagen de tamaño completo)

With Paging Enabled, the DetailsView Allows the User to View Any of the Products

Figura 16: Con la paginación habilitada, DetailsView permite al usuario ver cualquiera de los productos (Hacer clic para ver la imagen de tamaño completo)

Hablaremos más sobre la paginación en tutoriales futuros.

Un diseño más flexible para mostrar un registro a la vez

DetailsView es bastante rígido en la forma en que muestra cada registro devuelto desde ObjectDataSource. Es posible que deseemos una vista más flexible de los datos. Por ejemplo, en lugar de mostrar el nombre, la categoría, el proveedor, el precio y la información interrumpida del producto en una fila independiente, es posible que deseemos mostrar el nombre y el precio del producto en un encabezado de <h4>, con la información de categoría y proveedor que aparece por debajo del nombre y el precio en un tamaño de fuente más pequeño. Y es posible que no nos interese mostrar los nombres de propiedad (Producto, Categoría, etc.) junto a los valores.

El control FormView proporciona este nivel de personalización. En lugar de usar campos (como lo hacen GridView y DetailsView), FormView usa plantillas, lo que permite una combinación de controles web, HTML estáticos y sintaxis de enlace de datos. Si está familiarizado con el control Repeater de ASP.NET 1.x, puede considerar FormView como un Repeater para mostrar un único registro.

Agregue un control de FormView a la superficie de diseño de la página SimpleDisplay.aspx. Inicialmente, FormView se muestra como un bloque gris, que nos informa que necesitamos proporcionar, como mínimo, el control ItemTemplate.

The FormView Must Include an ItemTemplate

Figura 17: FormView debe incluir un ItemTemplate (Haga clic para ver la imagen de tamaño completo)

Puede enlazar FormView directamente a un control de origen de datos a través de la etiqueta inteligente de FormView, que creará automáticamente una ItemTemplate predeterminada (junto con una EditItemTemplate y InsertItemTemplate, si se establecen las propiedades InsertMethod y UpdateMethod del control ObjectDataSource). Sin embargo, para este ejemplo, vamos a enlazar los datos a FormView y especificar su ItemTemplate manualmente. Comience estableciendo la propiedad DataSourceID de FormView en el ID del control de ObjectDataSource, ObjectDataSource1. A continuación, cree el ItemTemplate para que muestre el nombre y el precio del producto en un elemento <h4> y los nombres de categoría y remitentes debajo en un tamaño de fuente menor.

<asp:FormView ID="FormView1" runat="server"
  DataSourceID="ObjectDataSource1" EnableViewState="False">
    <ItemTemplate>
        <h4><%# Eval("ProductName") %>
          (<%# Eval("UnitPrice", "{0:c}") %>)</h4>
        Category: <%# Eval("CategoryName") %>;
        Supplier: <%# Eval("SupplierName") %>
    </ItemTemplate>
</asp:FormView>

The First Product (Chai) is Displayed in a Custom Format

Figura 18: El primer producto (Chai) se muestra en un formato personalizado (Haga clic para ver la imagen de tamaño completo)

<%# Eval(propertyName) %> es la sintaxis de enlace de datos. El método Eval devuelve el valor de la propiedad especificada para el objeto actual que se enlaza al control de FormView. Consulte el artículo de Alex Homer Simplificación y sintaxis de enlace de datos extendido en ASP.NET 2.0 para obtener más información sobre las entradas y salidas de enlace de datos.

Al igual que DetailsView, FormView solo muestra el primer registro devuelto por ObjectDataSource. Puede habilitar la paginación en FormView para permitir que los visitantes recorran los productos de uno en uno.

Resumen

El acceso y visualización de datos desde una capa de lógica de negocios se puede lograr sin escribir una línea de código gracias al control de ObjectDataSource de ASP.NET 2.0. ObjectDataSource invoca un método especificado de una clase y devuelve los resultados. Estos resultados se pueden mostrar en un control web de datos enlazado a ObjectDataSource. En este tutorial hemos examinado el enlace de los controles GridView, DetailsView y FormView a ObjectDataSource.

Hasta ahora solo hemos visto cómo usar ObjectDataSource para invocar un método sin parámetros, pero ¿qué ocurre si queremos invocar un método que espera parámetros de entrada, como en la clase ProductBLL, método GetProductsByCategoryID(categoryID)? Para llamar a un método que espera uno o varios parámetros, debemos configurar ObjectDataSource para especificar los valores de estos parámetros. Veremos cómo hacerlo en nuestro siguiente tutorial.

¡Feliz programación!

Lecturas adicionales

Para obtener más información sobre los temas tratados en este tutorial, consulte los siguientes recursos:

Acerca del autor

Scott Mitchell, autor de siete libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha estado trabajando con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, entrenador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Puede ponerse en contacto con él via mitchell@4GuysFromRolla.com. o a través de su blog, que se puede encontrar en http://ScottOnWriting.NET.

Agradecimientos especiales a

Esta serie de tutoriales fue revisada por muchos revisores de gran ayuda. El revisor principal de este tutorial fue Hilton Giesenow. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.