작성자 : Christian Wenz
AJAX 컨트롤 도구 키트의 CascadingDropDown 컨트롤은 DropDownList 컨트롤을 확장하여 한 DropDownList의 변경 내용이 연결된 값을 다른 DropDownList에 로드합니다. 이렇게 하려면 특수 웹 서비스를 만들어야 합니다.
개요
AJAX 컨트롤 도구 키트의 CascadingDropDown 컨트롤은 DropDownList 컨트롤을 확장하여 한 DropDownList의 변경 내용이 연결된 값을 다른 DropDownList에 로드합니다. (예를 들어 한 목록은 미국 주 목록을 제공하고 다음 목록은 해당 주의 주요 도시로 채워집니다.) 이렇게 하려면 특수 웹 서비스를 만들어야 합니다.
단계
우선 데이터 원본이 필요합니다. 이 샘플에서는 AdventureWorks 데이터베이스 및 Microsoft SQL Server 2005 Express Edition을 사용합니다. 데이터베이스는 Visual Studio 설치의 선택적 부분(Express Edition 포함)이며 아래에서 https://go.microsoft.com/fwlink/?LinkId=64064별도의 다운로드로도 사용할 수 있습니다. AdventureWorks 데이터베이스는 SQL Server 2005 샘플 및 샘플 데이터베이스(다운로드 시 https://www.microsoft.com/download/details.aspx?id=10679)의 일부입니다. 데이터베이스를 설정하는 가장 쉬운 방법은 Microsoft SQL Server Management Studio(/sql/ssms/download-sql-server-management-studio-ssms)를 사용하고 데이터베이스 파일을 연결하는 AdventureWorks.mdf 것입니다.
이 샘플에서는 SQL Server 2005 Express Edition 인스턴스가 호출 SQLEXPRESS 되고 웹 서버와 동일한 컴퓨터에 상주한다고 가정합니다. 이는 기본 설정이기도 합니다. 설정이 다른 경우 데이터베이스에 대한 연결 정보를 조정해야 합니다.
ASP.NET AJAX 및 Control Toolkit의 기능을 활성화하려면, 페이지의 ScriptManager 요소 내 어디에든 컨트롤을 배치해야 합니다(<form> 요소 포함).
<asp:ScriptManager ID="asm" runat="server" />
다음 단계에서는 두 개의 DropDownList 컨트롤이 필요합니다. 이 샘플에서는 AdventureWorks의 공급업체 및 연락처 정보를 사용하므로 사용 가능한 공급업체에 대한 목록 하나와 사용 가능한 연락처에 대한 목록을 만듭니다.
<div>
Vendor: <asp:DropDownList ID="VendorsList" runat="server"/><br />
Contacts: <asp:DropDownList ID="ContactsList" runat="server"/><br />
</div>
그런 다음, 페이지에 두 개의 CascadingDropDown extender를 추가해야 합니다. 하나는 첫 번째(공급업체) 목록을 채우고 다른 하나는 두 번째(연락처) 목록을 채웁니다. 다음 특성을 설정해야 합니다.
-
ServicePath: 목록 항목을 제공하는 웹 서비스의 URL -
ServiceMethod: 목록 항목을 제공하는 웹 메서드 -
TargetControlID: 드롭다운 목록의 ID -
Category: 호출 시 웹 메서드에 제출되는 범주 정보 -
PromptText: 서버에서 목록 데이터를 비동기적으로 로드할 때 표시되는 텍스트 -
ParentControlID: (선택 사항) 현재 목록의 로드를 트리거하는 부모 드롭다운 목록
사용되는 프로그래밍 언어에 따라 문제의 웹 서비스 이름이 변경되지만 다른 모든 특성 값은 동일합니다. 다음은 첫 번째 드롭다운 목록의 CascadingDropDown 요소입니다.
<ajaxToolkit:CascadingDropDown ID="ccd1" runat="server"
ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetVendors"
TargetControlID="VendorsList" Category="Vendor"
PromptText="Select Vendor" />
두 번째 목록에 대한 컨트롤 확장기는 공급업체 목록에서 항목을 선택하면 연락처 목록에 연결된 요소가 로드되도록 특성을 설정 ParentControlID 해야 합니다.
<ajaxToolkit:CascadingDropDown ID="ccd2" runat="server"
ServicePath="CascadingDropdown1.vb.asmx" ServiceMethod="GetContactsForVendor"
TargetControlID="ContactsList" ParentControlID="VendorsList"
Category="Contact"
PromptText="Select Contact" />
그런 다음, 실제 작업은 다음과 같이 설정되는 웹 서비스에서 수행됩니다.
[ScriptService] 속성이 사용되지 않으면, ASP.NET AJAX가 클라이언트 측 스크립트 코드에서 웹 메서드에 액세스하기 위한 JavaScript 프록시를 생성할 수 없습니다.
<%@ 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
CascadingDropDown에서 호출하는 웹 메서드의 서명은 다음과 같습니다.
Public Function MethodNameHere(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
따라서 반환 값은 Control Toolkit에 의해 정의된 형식 CascadingDropDownNameValue 의 배열이어야 합니다. 이 GetVendors() 메서드는 구현하기가 매우 쉽습니다. 코드는 AdventureWorks 데이터베이스에 연결하고 처음 25개 공급업체를 쿼리합니다. 생성자의 첫 번째 매개 변수는 목록 항목의 캡션이고, 두 번째 매개 변수 CascadingDropDownNameValue 는 해당 값(HTML 요소의 값 특성)입니다 <option> . 코드는 다음과 같습니다.
<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
공급업체에 연결된 연락처(메서드 이름: GetContactsForVendor())를 가져오는 것은 약간 더 까다롭습니다. 우선 첫 번째 드롭다운 목록에서 선택된 공급업체를 결정해야 합니다. 컨트롤 도구 키트는 해당 작업에 대한 도우미 메서드를 정의합니다. 이 메서드는 ParseKnownCategoryValuesString() 드롭다운 데이터가 있는 StringDictionary 요소를 반환합니다.
<WebMethod()> _
Public Function GetContactsForVendor(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim VendorID As Integer
CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
보안상의 이유로 이 데이터의 유효성을 먼저 검사해야 합니다. 따라서 공급업체 항목이 있는 경우(첫 번째 CascadingDropDown 요소의 속성이 다음으로 설정되기 Category때문에"Vendor") 선택한 공급업체의 ID가 검색될 수 있습니다.
If Not kv.ContainsKey("Vendor") Or Not Int32.TryParse(kv("Vendor"),VendorID) Then
Throw New ArgumentException("Couldn't find vendor.")
End If
메서드의 나머지 부분은 상당히 간단하다. 공급업체의 ID는 해당 공급업체에 연결된 모든 연락처를 검색하는 SQL 쿼리의 매개 변수로 사용됩니다. 다시 한번 메서드는 형식 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
ASP.NET 페이지를 로드하고 잠시 후 공급업체 목록이 25개의 항목으로 채워집니다. 하나의 항목을 선택하고 두 번째 드롭다운 목록이 데이터로 채워지는 방법을 확인합니다.
첫 번째 목록이 자동으로 채워집니다(전체 크기 이미지를 보려면 클릭).
두 번째 목록은 첫 번째 목록의 선택 항목에 따라 채워집니다(전체 크기 이미지를 보려면 클릭).