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