Uso di CascadingDropDown con un database (C#)

di Christian Wenz

Scarica il PDF

Il controllo CascadingDropDown in AJAX Control Toolkit estende un controllo DropDownList in modo che le modifiche apportate a un elenco a discesa carichino i valori associati in un altro elenco a discesa. Per poter funzionare, è necessario creare un servizio Web speciale.

Panoramica

Il controllo CascadingDropDown in AJAX Control Toolkit estende un controllo DropDownList in modo che le modifiche apportate a un elenco a discesa carichino i valori associati in un altro elenco a discesa. Un elenco, ad esempio, fornisce un elenco di Stati Uniti e l'elenco successivo viene quindi riempito con le principali città in tale stato. Per poter funzionare, è necessario creare un servizio Web speciale.

Passaggi

Prima di tutto, è necessaria un'origine dati. Questo esempio usa il database AdventureWorks e microsoft SQL Server 2005 Express Edition. Il database è una parte facoltativa di un'installazione di Visual Studio (inclusa l'edizione express) ed è disponibile anche come download separato in https://go.microsoft.com/fwlink/?LinkId=64064. Il database AdventureWorks fa parte dell'SQL Server 2005 Samples and Sample Database (download in https://www.microsoft.com/download/details.aspx?id=10679). Il modo più semplice per impostare il database è usare microsoft SQL Server Management Studio (/sql/ssms/download-sql-server-management-studio-ssms) e collegare il file di AdventureWorks.mdf database.

Per questo esempio si presuppone che l'istanza del SQL Server 2005 Express Edition venga chiamata SQLEXPRESS e si trovi nello stesso computer del server Web. Questa è anche la configurazione predefinita. Se la configurazione è diversa, è necessario adattare le informazioni di connessione per il database.

Per attivare la funzionalità di ASP.NET AJAX e Control Toolkit, il ScriptManager controllo deve essere inserito ovunque nella pagina (ma all'interno dell'elementoform<>):

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

Nel passaggio successivo sono necessari due controlli DropDownList. In questo esempio si usano le informazioni sul fornitore e sul contatto di AdventureWorks, quindi si crea un elenco per i fornitori disponibili e uno per i contatti disponibili:

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

È quindi necessario aggiungere due estensioni CascadingDropDown alla pagina. Uno riempie il primo elenco (fornitori) e l'altro riempie il secondo elenco (contatti). Gli attributi seguenti devono essere impostati:

  • ServicePath: URL di un servizio Web che recapita le voci dell'elenco
  • ServiceMethod: metodo Web che recapita le voci di elenco
  • TargetControlID: ID dell'elenco a discesa
  • Category: informazioni sulla categoria inviate al metodo Web quando viene chiamato
  • PromptText: testo visualizzato quando si caricano in modo asincrono i dati dell'elenco dal server
  • ParentControlID: (facoltativo) elenco a discesa padre che attiva il caricamento dell'elenco corrente

A seconda del linguaggio di programmazione usato, il nome del servizio Web in questione cambia, ma tutti gli altri valori di attributo sono uguali. Ecco l'elemento CascadingDropDown per il primo elenco a discesa:

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

Gli extender di controllo per il secondo elenco devono impostare l'attributo ParentControlID in modo che la selezione di una voce nell'elenco fornitori attiva il caricamento di elementi associati nell'elenco contatti.

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

Il lavoro effettivo viene quindi eseguito nel servizio Web, che viene configurato come indicato di seguito. Si noti che l'attributo [ScriptService] viene usato, in caso contrario ASP.NET AJAX non può creare il proxy JavaScript per accedere ai metodi Web dal codice script lato client.

<%@ WebService Language="C#" Class="CascadingDropdown1" %>
using System.Web.Script.Services;
using AjaxControlToolkit;
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.SqlClient;
[ScriptService]
public class CascadingDropdown1 : System.Web.Services.WebService
{
 // ...
}

La firma dei metodi Web chiamati da CascadingDropDown è il seguente:

public CascadingDropDownNameValue[] MethodNameHere(string knownCategoryValues, 
    string category)

Il valore restituito deve quindi essere una matrice di tipo CascadingDropDownNameValue definita dal Toolkit di controllo. Il metodo è abbastanza semplice da implementare: il GetVendors() codice si connette al database AdventureWorks e esegue query sui primi 25 fornitori. Il primo parametro nel CascadingDropDownNameValue costruttore è il didascalia della voce dell'elenco, il secondo valore (attributo value nell'elemento HTMLoption<>). Il codice è il seguente:

[WebMethod]
public CascadingDropDownNameValue[] GetVendors(string knownCategoryValues, string category)
{
    SqlConnection conn = new SqlConnection("server=(local)\\SQLEXPRESS; 
    Integrated Security=true; Initial Catalog=AdventureWorks");
    conn.Open();
    SqlCommand comm = new SqlCommand("SELECT TOP 25 VendorID, Name 
    FROM Purchasing.Vendor",conn);
    SqlDataReader dr = comm.ExecuteReader();
    List<CascadingDropDownNameValue> l = new List<CascadingDropDownNameValue>();
    while (dr.Read())
    {
        l.Add(new CascadingDropDownNameValue(dr["Name"].ToString(),
        dr["VendorID"].ToString()));
    }
    conn.Close();
    return l.ToArray();
}

Ottenere i contatti associati per un fornitore (nome metodo: GetContactsForVendor()) è un po'più difficile. Prima di tutto, il fornitore selezionato nel primo elenco a discesa deve essere determinato. Control Toolkit definisce un metodo helper per tale attività: il ParseKnownCategoryValuesString() metodo restituisce un StringDictionary elemento con i dati a discesa:

[WebMethod]
public CascadingDropDownNameValue[] GetContactsForVendor(string knownCategoryValues, 
    string category)
{
    int VendorID;
    CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

Per motivi di sicurezza, questi dati devono essere convalidati prima. Quindi, se è presente una voce Vendor (perché la Category proprietà del primo elemento CascadingDropDown è impostata su "Vendor"), l'ID del fornitore selezionato può essere recuperato:

if (!kv.ContainsKey("Vendor") || !Int32.TryParse(kv["Vendor"],out VendorID)) 
{
    throw new ArgumentException("Couldn't find vendor.");
};

Il resto del metodo è abbastanza dritto, quindi. L'ID del fornitore viene usato come parametro per una query SQL che recupera tutti i contatti associati per tale fornitore. Ancora una volta, il metodo restituisce una matrice di tipo CascadingDropDownNameValue.

SqlConnection conn = new SqlConnection("server=(local)\\SQLEXPRESS; 
 Integrated Security=true; Initial Catalog=AdventureWorks");
 conn.Open();
 SqlCommand comm = 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);
 SqlDataReader dr = comm.ExecuteReader();
 List<CascadingDropDownNameValue> l = new List<CascadingDropDownNameValue>();
 while (dr.Read())
 {
 l.Add(new CascadingDropDownNameValue(
 dr["FirstName"].ToString() + " " + dr["LastName"].ToString(),
 dr["ContactID"].ToString()));
 }
 conn.Close();
 return l.ToArray();
}

Caricare la pagina ASP.NET e dopo un breve periodo di riempimento dell'elenco fornitori con 25 voci. Selezionare una voce e notare come viene riempito il secondo elenco a discesa con i dati.

Il primo elenco viene compilato automaticamente

Il primo elenco viene riempito automaticamente (fare clic per visualizzare l'immagine full-size)

Il secondo elenco viene compilato in base alla selezione nella prima lista

Il secondo elenco viene compilato in base alla selezione nella prima lista (Fare clic per visualizzare l'immagine full-size)