In this article I will explain with an example, how to populate Cascading i.e. Dependent Country, State and City DropDownLists using jQuery AJAX in ASP.Net MVC Razor.
The Cascading i.e. Dependent Country, State and City DropDownLists will be populated from database by making use of jQuery AJAX in ASP.Net MVC Razor.
Note: For beginners in using ADO.Net with ASP.Net MVC, please refer my article ASP.Net MVC: ADO.Net Tutorial with example.
 
 
Database
Three tables Countries, State and City are created with the following schema.
Countries Table
Cascading (Dependent) Country State City DropDownLists using jQuery AJAX in ASP.Net MVC
 
States Table
Cascading (Dependent) Country State City DropDownLists using jQuery AJAX in ASP.Net MVC
 
Cities Table
Cascading (Dependent) Country State City DropDownLists using jQuery AJAX in ASP.Net MVC
 
Note: You can download the database table SQL by clicking the download link below.
          Download SQL file
 
 
Namespaces
You will need to import the following namespaces.
using System.Configuration;
using System.Data.SqlClient;
using System.Collections.Generic;
 
 
Model
The following Model class consists of three Generic List Collection properties of SelectListItem class (which is an in-built ASP.Net MVC class and has all the properties needed for populating a DropDownList) for holding the Country, State and City records.
The Model class also contains three Integer type properties for holding the selected Country, State and City values.
public class CascadingModel
{
    public CascadingModel()
    {
        this.Countries = new List<SelectListItem>();
        this.States = new List<SelectListItem>();
        this.Cities = new List<SelectListItem>();
    }
 
    public List<SelectListItem> Countries { get; set; }
    public List<SelectListItem> States { get; set; }
    public List<SelectListItem> Cities { get; set; }
 
    public int CountryId { get; set; }
    public int StateId { get; set; }
    public int CityId { get; set; }
}
 
 
Controller
The Controller consists of three Action methods.
Action method for handling GET operation
Inside this Action method, the Countries DropDownList is populated using the PopulateDropDown method which executes the SQL query passed as parameter and returns a Generic List of SelectListItem class.
The list of Countries is assigned to the Countries property of the Model class which is ultimately returned to the View.
 
Action method for handling AJAX operation
This Action method is executed when the jQuery AJAX call is made from View on changed event of the Country and State DropDownLists.
It accepts type and value parameter and based on the type i.e. Country or State, the list of States or Cities respectively are fetched from the database and returned to View as JSON.
 
Action method for handling POST operation
This Action method handles the call made from the POST function from the View and is executed when the Submit button is clicked.
When the Form is submitted, the posted values are captured in three variables one for each i.e. Country, State and City.  
Using these values, the Countries, States and Cities are again populated in the Model class object which is then returned back to the View.
public class HomeController : Controller
{
    // GET: Home
    public ActionResult Index()
    {
        CascadingModel model = new CascadingModel();
        model.Countries = PopulateDropDown("SELECT CountryId, CountryName FROM Countries", "CountryName", "CountryId");
        return View(model);
    }
 
    [HttpPost]
    public JsonResult AjaxMethod(string type, int value)
    {
        CascadingModel model = new CascadingModel();
        switch (type)
        {
            case "CountryId":
                model.States = PopulateDropDown("SELECT StateId, StateName FROM States WHERE CountryId = " + value, "StateName", "StateId");
                break;
            case "StateId":
                model.Cities = PopulateDropDown("SELECT CityId, CityName FROM Cities WHERE StateId = " + value, "CityName", "CityId");
                break;
        }
        return Json(model);
    }
 
    [HttpPost]
    public ActionResult Index(int countryId, int stateId, int cityId)
    {
        CascadingModel model = new CascadingModel();
        model.Countries = PopulateDropDown("SELECT CountryId, CountryName FROM Countries", "CountryName", "CountryId");
        model.States = PopulateDropDown("SELECT StateId, StateName FROM States WHERE CountryId = " + countryId, "StateName", "StateId");
        model.Cities = PopulateDropDown("SELECT CityId, CityName FROM Cities WHERE StateId = " + stateId, "CityName", "CityID");
        return View(model);
    }
 
    private static List<SelectListItem> PopulateDropDown(string query, string textColumn, string valueColumn)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        string constr = ConfigurationManager.ConnectionStrings["Constring"].ConnectionString;
        using (SqlConnection con = new SqlConnection(constr))
        {
            using (SqlCommand cmd = new SqlCommand(query))
            {
                cmd.Connection = con;
                con.Open();
                using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        items.Add(new SelectListItem
                        {
                            Text = sdr[textColumn].ToString(),
                            Value = sdr[valueColumn].ToString()
                        });
                    }
                }
                con.Close();
            }
        }
 
        return items;
    }
}
 
 
View
Inside the View, in the very first line the CascadingModel class is declared as Model for the View.
The View consists of an HTML Form which has been created using the Html.BeginForm method with the following parameters.
ActionNameName of the Action. In this case the name is Index.
ControllerName – Name of the Controller. In this case the name is Home.
FormMethod – It specifies the Form Method i.e. GET or POST. In this case it will be set to POST.
Inside the Form, the Country, State and City DropDownLists are populated using DropDownListFor HTML Helper function.
Each DropDownList has been assigned a jQuery OnChange event handler. Inside this event handler, an AJAX call is made to the AjaxMethod Action method and based on the type value, the appropriate DropDownList is populated from the results.
Inside the jQuery document ready event handler, if all the three DropDownLists are populated then the selected values are displayed using JavaScript Alert Message Box.
@model Cascading_DropDownList_MVC.Models.CascadingModel
 
@{
    Layout = null;
}
 
<!DOCTYPE html>
 
<html>
<head>
    <meta name="viewport" content="width=device-width"/>
    <title>Index</title>
</head>
<body>
    @using (Html.BeginForm("Index", "Home", FormMethod.Post))
    {
        @Html.DropDownListFor(m => m.CountryId, Model.Countries, "Please select")
        <br/>
        <br/>
        @Html.DropDownListFor(m => m.StateId, Model.States, "Please select")
        <br/>
        <br/>
        @Html.DropDownListFor(m => m.CityId, Model.Cities, "Please select")
        <br/>
        <br/>
        <input type="submit" value="Submit"/>
    }
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script type="text/javascript">
        $(function () {
            $("select").each(function () {
                if ($(this).find("option").length <= 1) {
                    $(this).attr("disabled", "disabled");
                }
            });
 
            $("select").change(function () {
                var value = 0;
                if ($(this).val() != "") {
                    value = $(this).val();
                }
                var id = $(this).attr("id");
                $.ajax({
                    type: "POST",
                    url: "/Home/AjaxMethod",
                    data: '{type: "' + id + '", value: ' + value + '}',
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (response) {
                        var dropDownId;
                        var list;
                        switch (id) {
                            case "CountryId":
                                list = response.States;
                                DisableDropDown("#StateId");
                                DisableDropDown("#CityId");
                                PopulateDropDown("#StateId", list);
                                break;
                            case "StateId":
                                dropDownId = "#CityId";
                                list = response.Cities;
                                DisableDropDown("#CityId");
                                PopulateDropDown("#CityId", list);
                                break;
                        }
                       
                    },
                    failure: function (response) {
                        alert(response.responseText);
                    },
                    error: function (response) {
                        alert(response.responseText);
                    }
                });
            });
        });
 
        function DisableDropDown(dropDownId) {
            $(dropDownId).attr("disabled", "disabled");
            $(dropDownId).empty().append('<option selected="selected" value="0">Please select</option>');
        }
 
        function PopulateDropDown(dropDownId, list) {
            if (list != null && list.length > 0) {
                $(dropDownId).removeAttr("disabled");
                $.each(list, function () {
                    $(dropDownId).append($("<option></option>").val(this['Value']).html(this['Text']));
                });
            }
        }
 
        $(function () {
            if ($("#CountryId").val() != "" && $("#StateId").val() != "" && $("#CityId").val() != "") {
                var message = "Country: " + $("#CountryId option:selected").text();
                message += "\nState: " + $("#StateId option:selected").text();
                message += "\nCity: " + $("#CityId option:selected").text();
                alert(message);
            }
        });
    </script>
</body>
</html>
 
 
Screenshot
Cascading (Dependent) Country State City DropDownLists using jQuery AJAX in ASP.Net MVC
 
 
Downloads