In this article I will explain how to make use of ASP.Net AJAX Control Toolkit CascadingDropDown control in ASP.Net Website. Three AJAX Cascading Dropdowns along with the three corresponding ASP.Net DropDownLists will be populated from database with values of Country State City using Web Service and Web Methods. 
	
		On Page Load list of Countries is populated, when Country is selected, the list of States will be populated, and when a State is chosen list of Cities will be populated, thus at the end we get a Country, State and City Cascading DropDownLists implemented using ASP.Net AJAX CascadingDropDown control.
	
		Finally the article also explains how to access the values of the ASP.Net AJAX CascadingDropDown DropDownList Server Side on button click.
	
		 
	
		 
	
	Database
	Three tables Countries, State and City are created with the following schema.
	Countries Table
 
	States Table
 
	Cities Table
 
	
		Note: You can download the database table SQL by clicking the download link below.
	
 
	
		 
	
		Creating the Database
	
		You will have to simply execute the script named CreateCascadingDatabase.sql stored in the SQL Folder of the attached sample and it will create the complete database with tables and data.
	
		 
	
		Using the ASP.Net AJAX Control Toolkit CascadingDropDown Control
	
		1. Register the AJAX Control Toolkit Library after adding reference to your project
	
		 
	
		
			<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
	 
	
		 
	
		2. Drag an ASP.Net AJAX ToolScriptManager on the page.
	
		 
	
		
			<cc1:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
		
			</cc1:ToolkitScriptManager>
	 
	
		 
	
		3. Then you need to add the AJAX CascadingDropDown control next to the DropDownList control for which you want to use as Cascading DropDownList.
	
		 
	
		
			<asp:DropDownList ID="ddlCountries" runat="server" Width = "150">
		
			</asp:DropDownList>
		
			<cc1:CascadingDropDown ID="cdlCountries" TargetControlID="ddlCountries" PromptText="Select Country" PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetCountries" runat="server" Category="CountryId" />
	 
	
		 
	
		 
	
		HTML Markup
	
		The HTML Markup consists of three ASP.Net DropDownLists along with their corresponding three ASP.Net AJAX CascadingDropDowns. At the end there’s an ASP.Net Button which will used to submit the selected values of the ASP.Net AJAX CascadingDropDown DropDownList Server Side.
	
		
			<cc1:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
		
			</cc1:ToolkitScriptManager>
		
			<table>
		
			    <tr>
		
			        <td style="width: 80px">
		
			            Country:
		
			        </td>
		
			        <td>
		
			            <asp:DropDownList ID="ddlCountries" runat="server" Width="150">
		
			            </asp:DropDownList>
		
			            <cc1:CascadingDropDown ID="cdlCountries" TargetControlID="ddlCountries" PromptText="Select Country"
		
			                PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetCountries" runat="server"
		
			                Category="CountryId" LoadingText="Loading..." />
		
			        </td>
		
			    </tr>
		
			    <tr>
		
			        <td>
		
			            State:
		
			        </td>
		
			        <td>
		
			            <asp:DropDownList ID="ddlStates" runat="server" Width="150">
		
			            </asp:DropDownList>
		
			            <cc1:CascadingDropDown ID="cdlStates" TargetControlID="ddlStates" PromptText="Select State"
		
			                PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetStates" runat="server"
		
			                Category="StateId" ParentControlID="ddlCountries" LoadingText="Loading..." />
		
			        </td>
		
			    </tr>
		
			    <tr>
		
			        <td>
		
			            City:
		
			        </td>
		
			        <td>
		
			            <asp:DropDownList ID="ddlCities" runat="server" Width="150">
		
			            </asp:DropDownList>
		
			            <cc1:CascadingDropDown ID="cdlCities" TargetControlID="ddlCities" PromptText="Select City"
		
			                PromptValue="" ServicePath="ServiceCS.asmx" ServiceMethod="GetCities" runat="server"
		
			                Category="CityId" ParentControlID="ddlStates" LoadingText="Loading..." />
		
			        </td>
		
			    </tr>
		
			    <tr>
		
			        <td>
		
			        </td>
		
			        <td>
		
			            <asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />
		
			        </td>
		
			    </tr>
		
			</table>
	 
	
		 
	
		 
	
		 
	
		CascadingDropDown Properties 
	
		Below are some important properties of the AJAX CascadingDropDown
	
		TargetControlID – Here we need to set the ID of the DropDownList control for which you want to make an AJAX Cascading DropDownList.
	
		 
	
		ServicePath – Here we set the URL of the Web Service that will act as source of data for the AJAX CascadingDropDown DropDownList.
	
		 
	
		ServiceMethod – Here we set the name of the Web Method that will be used to populate the AJAX CascadingDropDown DropDownList.
	
		 
	
		PromptText – This property is the Text part that of the first or the default item that will be displayed in the AJAX CascadingDropDown DropDownList.
	
		 
	
		PromptValue – This property is the Value part that of the first or the default item that will be displayed in the AJAX CascadingDropDown DropDownList.
	
		 
	
		Category – This property is used to specify the Category for the AJAX CascadingDropDown DropDownList, Category value is passed as parameter to the Child or dependent AJAX CascadingDropDown DropDownList ServiceMethod i.e. Web Method.
	
		 
	
		ParentControlID – This property is used to set the ID of the DropDownList on whose selection the DropDownList will trigger the data population process.
	
		 
	
		LoadingText– This property used to display the loading text when the call is made to the Web Method until the data is populated in the AJAX CascadingDropDown DropDownList.
	
		 
	
		 
	
		 
	
		Web Service for handing CascadingDropDown AJAX Calls
	
		Below is the code of the Web Servicee that will act as the source of data for the ASP.Net AJAX CascadingDropDown DropDownLists. There are three Web Methods in the Web Service, one for each AJAX CascadingDropDown i.e. Country, State and City. 
	
		All the three Web Methods accept knownCategoryValues as parameter, which is nothing but combination of the Category and the Selected Value from the Parent DropDownList. For example for the State AJAX CascadingDropDown the value of knownCategoryValues looks like CountryId:1; where CountryId is the Category specified the Country DropDownList and the value 1 is the Country Id for USA.  
	
		If the CascadingDropDown does not have any parent then the knownCategoryValues is blank.
	
		The return type of each Web Method is an Array of CascadingDropDownNameValue class objects, which belongs to the AJAX Control Toolkit namespace.
	
		Each of the three Web Methods get the records from database through a generic function named as GetData which returns the fetched item as an Array of CascadingDropDownNameValue class objects after fetching records from database using DataReader.
	
		C#
	
		
			using System;
		
			using System.Web;
		
			using System.Web.Services;
		
			using System.Data;
		
			using System.Data.SqlClient;
		
			using System.Configuration;
		
			using AjaxControlToolkit;
		
			using System.Collections.Generic;
		
			 
		
			///<summary>
		
			/// Summary description for ServiceCS
		
			///</summary>
		
			[WebService(Namespace = "http://tempuri.org/")]
		
			[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
		
			[System.Web.Script.Services.ScriptService]
		
			public class ServiceCS : System.Web.Services.WebService
		
			{
		
			    [WebMethod]
		
			    public CascadingDropDownNameValue[] GetCountries(string knownCategoryValues)
		
			    {
		
			        string query = "SELECT CountryName, CountryId FROM Countries";
		
			        List<CascadingDropDownNameValue> countries = GetData(query);
		
			        return countries.ToArray();
		
			    }
		
			 
		
			    [WebMethod]
		
			    public CascadingDropDownNameValue[] GetStates(string knownCategoryValues)
		
			    {
		
			        string country = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)["CountryId"];
		
			        string query = string.Format("SELECT StateName, StateId FROM States WHERE CountryId = {0}", country);
		
			        List<CascadingDropDownNameValue> states = GetData(query);
		
			        return states.ToArray();
		
			    }
		
			 
		
			    [WebMethod]
		
			    public CascadingDropDownNameValue[] GetCities(string knownCategoryValues)
		
			    {
		
			        string state = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)["StateId"];
		
			        string query = string.Format("SELECT CityName, CityId FROM Cities WHERE StateId = {0}", state);
		
			        List<CascadingDropDownNameValue> cities = GetData(query);
		
			        return cities.ToArray();
		
			    }
		
			 
		
			    private List<CascadingDropDownNameValue> GetData(string query)
		
			    {
		
			       string conString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
		
			        SqlCommand cmd = new SqlCommand(query);
		
			        List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
		
			        using (SqlConnection con = new SqlConnection(conString))
		
			        {
		
			            con.Open();
		
			            cmd.Connection = con;
		
			            using (SqlDataReader reader = cmd.ExecuteReader())
		
			            {
		
			                while (reader.Read())
		
			                {
		
			                    values.Add(new CascadingDropDownNameValue
		
			                    {
		
			                        name = reader[0].ToString(),
		
			                        value = reader[1].ToString()
		
			                    });
		
			                }
		
			                reader.Close();
		
			                con.Close();
		
			                return values;
		
			            }
		
			        }
		
			    }
		
			}
	 
	
		 
	
		VB.Net
	
		
			Imports System.Web
		
			Imports System.Web.Services
		
			Imports System.Web.Services.Protocols
		
			Imports System.Data
		
			Imports System.Data.SqlClient
		
			Imports System.Configuration
		
			Imports AjaxControlToolkit
		
			Imports System.Collections.Generic
		
			 
		
			<WebService([Namespace]:="http://tempuri.org/")> _
		
			<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
		
			<System.Web.Script.Services.ScriptService()> _
		
			Public Class ServiceVB
		
			    Inherits System.Web.Services.WebService
		
			    <WebMethod()> _
		
			    Public Function GetCountries(knownCategoryValues As String) As CascadingDropDownNameValue()
		
			        Dim query As String = "SELECT CountryName, CountryId FROM Countries"
		
			        Dim countries As List(Of CascadingDropDownNameValue) = GetData(query)
		
			        Return countries.ToArray()
		
			    End Function
		
			 
		
			    <WebMethod()> _
		
			    Public Function GetStates(knownCategoryValues As String) As CascadingDropDownNameValue()
		
			        Dim country As String = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)("CountryId")
		
			        Dim query As String = String.Format("SELECT StateName, StateId FROM States WHERE CountryId = {0}", country)
		
			        Dim states As List(Of CascadingDropDownNameValue) = GetData(query)
		
			        Return states.ToArray()
		
			    End Function
		
			 
		
			    <WebMethod()> _
		
			    Public Function GetCities(knownCategoryValues As String) As CascadingDropDownNameValue()
		
			        Dim state As String = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)("StateId")
		
			        Dim query As String = String.Format("SELECT CityName, CityId FROM Cities WHERE StateId = {0}", state)
		
			        Dim cities As List(Of CascadingDropDownNameValue) = GetData(query)
		
			        Return cities.ToArray()
		
			    End Function
		
			 
		
			    Private Function GetData(query As String) As List(Of CascadingDropDownNameValue)
		
			        Dim conString As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
		
			        Dim cmd As New SqlCommand(query)
		
			        Dim values As New List(Of CascadingDropDownNameValue)()
		
			        Using con As New SqlConnection(conString)
		
			            con.Open()
		
			            cmd.Connection = con
		
			            Using reader As SqlDataReader = cmd.ExecuteReader()
		
			                While reader.Read()
		
			                    values.Add(New CascadingDropDownNameValue() With { _
		
			                     .name = reader(0).ToString(), _
		
			                     .value = reader(1).ToString() _
		
			                    })
		
			                End While
		
			                reader.Close()
		
			                con.Close()
		
			                Return values
		
			            End Using
		
			        End Using
		
			    End Function
		
			End Class
	 
	
		 
	
	
		 
	
		Accessing the Value of ASP.Net AJAX CascadingDropDown DropDownList Server Side
	
		On the click of the Button the following event handler is executed where I have described how to access the Selected Text and Value of the ASP.Net AJAX CascadingDropDown DropDownList.
	
		C#
	
		
			protected void btnSubmit_Click(object sender, EventArgs e)
		
			{
		
			    string message = "Country: " + ddlCountries.SelectedItem.Text;
		
			    message += " State: " + ddlStates.SelectedItem.Text;
		
			    message += " City: " + ddlCities.SelectedItem.Text;
		
			    ClientScript.RegisterStartupScript(GetType(), "alert", "alert('" + message + "');", true);
		
			}
	 
	
		 
	
		VB.Net
	
		
			Protected Sub btnSubmit_Click(sender As Object, e As EventArgs)
		
			    Dim message As String = "Country: " + ddlCountries.SelectedItem.Text
		
			    message += " State: " + ddlStates.SelectedItem.Text
		
			    message += " City: " + ddlCities.SelectedItem.Text
		
			    ClientScript.RegisterStartupScript(Me.GetType(), "alert", "alert('" + message + "');", True)
		
			End Sub
	 
	
		 
	
	
		 
	
		Handling the Event Validation Error
	
		You might land into the following error when you click Submit Button
	
		
			Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
	 
	
		 
	
		To resolve the above error you must set the property EnableEventValidation = "false"  in the @Page Directive as shown below
	
	
	
		 
	
		Demo
	
	
		 
	
		 
	
		Downloads