Usar CascadingDropDown con una base de datos (VB)

por Christian Wenz

Descargar código o Descargar PDF

El control CascadingDropDown en el kit de herramientas de control de AJAX extiende un control DropDownList para que los cambios en un objeto DropDownList carguen los valores asociados en otro DropDownList. Para que esto funcione, se debe crear un servicio Web especial.

Información general

El control CascadingDropDown en el kit de herramientas de control de AJAX extiende un control DropDownList para que los cambios en un objeto DropDownList carguen los valores asociados en otro DropDownList. (Por ejemplo, una lista proporciona una lista de Estados de EE. UU. y la siguiente lista se rellena con las ciudades principales en ese estado). Para que esto funcione, se debe crear un servicio Web especial.

Pasos

En primer lugar, se necesita un origen de datos. Este ejemplo utiliza la base de datos AdventureWorks y el Microsoft SQL Server 2005 Express Edition. La base de datos es una parte opcional de una instalación de Visual Studio (incluida Express Edition) y también está disponible como descarga independiente en https://go.microsoft.com/fwlink/?LinkId=64064. La base de datos AdventureWorks forma parte de los ejemplos de SQL Server 2005 y de las bases de datos de ejemplo (descarga en https://www.microsoft.com/downloads/details.aspx?FamilyID=e719ecf7-9f46-4312-af89-6ad8702e4e6e&D isplaylang = en). La forma más sencilla de configurar la base de datos es usar el Microsoft SQL Server Management Studio Express (https://www.microsoft.com/downloads/details.aspx?FamilyID=c243a5ae-4bd1-4e3d-94b8-5a0f62bf7796&D isplaylang = en) y adjuntar el archivo de base de datos AdventureWorks.mdf.

En este ejemplo, se supone que la instancia del SQL Server 2005 Express Edition se denomina SQLEXPRESS y reside en el mismo equipo que el servidor Web. Esta es también la configuración predeterminada. Si el programa de instalación es diferente, tendrá que adaptar la información de conexión de la base de datos.

Para activar la funcionalidad de ASP.NET AJAX y el kit de herramientas de control, el control ScriptManager debe colocarse en cualquier parte de la página (pero dentro del <formelemento >):

<asp:ScriptManager ID="asm" runat="server" />

En el paso siguiente, se necesitan dos controles DropDownList. En este ejemplo, usamos la información de proveedor y contacto de AdventureWorks, por lo que creamos una lista para los proveedores disponibles y otra para los contactos disponibles:

<div>
 Vendor: <asp:DropDownList ID="VendorsList" runat="server"/><br />
 Contacts: <asp:DropDownList ID="ContactsList" runat="server"/><br />
</div>

A continuación, se deben agregar dos extensores CascadingDropDown a la página. Una rellena la primera lista (proveedores) y la otra rellena la segunda lista (contactos). Se deben establecer los siguientes atributos:

  • ServicePath: dirección URL de un servicio Web que entrega las entradas de la lista
  • ServiceMethod: método Web que entrega las entradas de la lista
  • TargetControlID: ID. de la lista desplegable
  • Category: información de categoría que se envía al método Web cuando se llama
  • PromptText: texto que se muestra cuando se cargan datos de lista de forma asincrónica desde el servidor
  • ParentControlID: (opcional) lista desplegable principal que desencadena la carga de la lista actual

Dependiendo del lenguaje de programación utilizado, el nombre del servicio Web en cuestión cambia, pero todos los demás valores de atributo son los mismos. Este es el elemento CascadingDropDown de la primera lista desplegable:

<ajaxToolkit:CascadingDropDown ID="ccd1" runat="server"
 ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetVendors"
 TargetControlID="VendorsList" Category="Vendor"
 PromptText="Select Vendor" />

Los extensores de control de la segunda lista deben establecer el atributo de ParentControlID para que la selección de una entrada en la lista de proveedores desencadene la carga de elementos asociados en la lista de contactos.

<ajaxToolkit:CascadingDropDown ID="ccd2" runat="server"
 ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetContactsForVendor"
 TargetControlID="ContactsList" ParentControlID="VendorsList"
 Category="Contact"
 PromptText="Select Contact" />

El trabajo real se realiza entonces en el servicio Web, que se configura como se indica a continuación. Tenga en cuenta que se usa el atributo [ScriptService]; de lo contrario, ASP.NET AJAX no puede crear el proxy de JavaScript para tener acceso a los métodos Web desde el código de script del lado cliente.

<%@ WebService Language="VB" Class="CascadingDropdown1" %>
Imports System.Web.Script.Services
Imports AjaxControlToolkit
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Collections.Generic
Imports System.Collections.Specialized
Imports System.Data.SqlClient
<ScriptService()> _
Public Class CascadingDropdown1
 Inherits System.Web.Services.WebService
 ' ...
End Class

La firma de los métodos Web a los que llama CascadingDropDown es la siguiente:

Public Function MethodNameHere(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()

Por lo tanto, el valor devuelto debe ser una matriz de tipo CascadingDropDownNameValue definida por el kit de herramientas del control. El método GetVendors() es bastante fácil de implementar: el código se conecta a la base de datos AdventureWorks y consulta los 25 primeros proveedores. El primer parámetro del constructor CascadingDropDownNameValue es el título de la entrada de la lista, el segundo, su valor (atributo de valor en el <de HTML optionelemento >). Este es el código:

<WebMethod()> _
Public Function GetVendors(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
 Dim conn As New SqlConnection("server=(local)\SQLEXPRESS; Integrated Security=true; Initial Catalog=AdventureWorks")
 conn.Open()
 Dim comm As New SqlCommand( _
 "SELECT TOP 25 VendorID, Name FROM Purchasing.Vendor", conn)
 Dim dr As SqlDataReader = comm.ExecuteReader()
 Dim l As New List(Of CascadingDropDownNameValue)
 While (dr.Read())
 l.Add(New CascadingDropDownNameValue(dr("Name").ToString(),dr("VendorID").ToString()))
 End While
 conn.Close()
 Return l.ToArray()
End Function

Obtener los contactos asociados para un proveedor (nombre de método: GetContactsForVendor()) es un poco más complicado. En primer lugar, se debe determinar el proveedor que se ha seleccionado en la primera lista desplegable. El kit de herramientas de control define un método auxiliar para esa tarea: el método ParseKnownCategoryValuesString() devuelve un elemento StringDictionary con los datos desplegables:

<WebMethod()> _
Public Function GetContactsForVendor(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
 Dim VendorID As Integer
 CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)

Por motivos de seguridad, estos datos se deben validar primero. Por lo tanto, si hay una entrada de proveedor (porque la propiedad Category del primer elemento CascadingDropDown está establecida en "Vendor"), se puede recuperar el ID. del proveedor seleccionado:

If Not kv.ContainsKey("Vendor") Or Not Int32.TryParse(kv("Vendor"),VendorID) Then
 Throw New ArgumentException("Couldn't find vendor.")
 End If

El resto del método es bastante directo y, a continuación,. El identificador del proveedor se usa como parámetro de una consulta SQL que recupera todos los contactos asociados para ese proveedor. Una vez más, el método devuelve una matriz de tipo CascadingDropDownNameValue.

Dim conn As New SqlConnection("server=(local)\SQLEXPRESS; Integrated Security=true; Initial Catalog=AdventureWorks")
 conn.Open()
 Dim comm As New SqlCommand("SELECT Person.Contact.ContactID, FirstName, LastName FROM Person.Contact,Purchasing.VendorContact WHERE VendorID=@VendorID AND Person.Contact.ContactID=Purchasing.VendorContact.ContactID",conn)
 comm.Parameters.AddWithValue("@VendorID", VendorID)
 Dim dr As SqlDataReader = comm.ExecuteReader()
 Dim l As New List(Of CascadingDropDownNameValue)
 While (dr.Read())
 l.Add(New CascadingDropDownNameValue(dr("FirstName").ToString() & " " & dr("LastName").ToString(),dr("ContactID").ToString()))
 End While
 conn.Close()
 Return l.ToArray()
End Function

Cargue la página ASP.NET y, después de un breve, la lista de proveedores se rellena con 25 entradas. Seleccione una entrada y observe cómo la segunda lista desplegable se rellena con datos.

la primera lista se rellena automáticamente

La primera lista se rellena automáticamente (haga clic para ver la imagen de tamaño completo)

la segunda lista se rellena de acuerdo con la selección de la primera lista

La segunda lista se rellena de acuerdo con la selección de la primera lista (haga clic para ver la imagen de tamaño completo)