If you are working with Forms in ASP.NET Core then you may have to create cascading dropdownlist or dependent dropdownlist in ASP.NET Core MVC, so in this article, I have mentioned step by step procedure to create (State-Country) cascading dropdownlist in ASP.NET Core MVC

Suppose, we have below SQL Server database tables(State and Country), which we will use for cascading dropdown list:

cascading-dropdownlist-in-asp-net-core-mvc-state-country

Step 1: Create a new ASP.NET Core project in Visual Studio, I am using VS 2022, so after opening Visual Studio Click on "Create new project" -> then select "ASP.NET Core (Model-View-Controller) template" -> in Next step, Select .NET Core version (I am using .NET Core 6) -> Click "Create".

Step 2: Once Visual Studio Generates .NET Core template files, we will need to install below Nuget Package to connect to database using EF Core

Install-Package Microsoft.EntityFrameworkCore.SqlServer

Step 3: In the next step, we will create Class files for Database Context, Country and State table

So in Solution Explorer, right-click on the "Models" Folder -> Select "Add" -> Then Select "Class", name it as Country.cs

namespace CascadingDropDownListCore.Models
{
    public class Country
    {
        public int Id {get;set;}
        public string CountryName { get;set;}
    }
}

Similarly, add "State.cs"

namespace CascadingDropDownListCore.Models
{
    public class State
    {
        public int Id { get; set; }
        public string StateName { get; set; }
        public int CountryID { get; set; }
    }
}

and "DBCtx.cs"

using Microsoft.EntityFrameworkCore;

namespace CascadingDropDownListCore.Models
{
    public class DBCtx : DbContext
    {
        public DBCtx(DbContextOptions<DBCtx> options) : base(options)
        {
        }

        public DbSet<State> State { get; set; }
        public DbSet<Country> Country { get; set; }
    }
}

Step 4: Add the Connection string in appsettings.json file

  "ConnectionStrings": {
    "MyConnection": "Data Source=DESKTOP-DOG5T0Q\\SQLEXPRESS;Initial Catalog=CountryState;Integrated security=true;TrustServerCertificate=True"
  }

Step 5: Now, we will need to read the connection string in Program.cs (As I am using .NET 6, so there is no startup.cs) and add database context in the application, so C# Code would be as below

using CascadingDropDownListCore.Models;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

string conStr = builder.Configuration.GetConnectionString("MyConnection");
builder.Services.AddDbContext<DBCtx>(options => options.UseSqlServer(conStr));

Step 6: Navigate to HomeController.cs, where we will add a database context variable and also add code to fetch Country list from the database and also add ActionMethod to fetch State List on Country Dropdown change.

So, here is the complete C# Code for HomeController.cs

using CascadingDropDownListCore.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using System.Security.Cryptography;

namespace CascadingDropDownListCore.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private DBCtx Context { get; }

        public HomeController(ILogger<HomeController> logger, DBCtx _context)
        {
            _logger = logger;
            Context = _context;
        }

        public IActionResult Index()
        {
            //get country list as SelectListItem
            ViewBag.Country =  Context.Country.ToList().Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.CountryName }).ToList();
            return View();
        }

        //this method is called using jQuery
        public IActionResult GetStates(int id)
        {
            //get state list as SelectListItem
            var statesList = Context.State.Where(s => s.CountryID == id).ToList().Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.StateName }).ToList();
            return Json(statesList);
        }
        //method where form is posted
        [HttpPost]
        public IActionResult Index(int Country, int State)
        {
            //get selected country/state name
            ViewBag.SelectedCountry = Context.Country.Where(a=>a.Id == Country).FirstOrDefault().CountryName;
            ViewBag.SelectedState = Context.State.Where(a => a.Id == State).FirstOrDefault().StateName;

            //again get country list as SelectListItem 
            ViewBag.Country = Context.Country.ToList().Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.CountryName }).ToList();
            return View();
        }
    }
}

We have also added "Index" Action, POST method, which will be called when form is submitted once dropdown values are selected.

Step 7: Navigate to "Views"->"Home"->"Index.cshtml"

@{
    ViewData["Title"] = "Home Page";
}
<div class="row">
    <div class="col-md-4">
        <form asp-action="Index">
            <div class="form-group">
                <label class="control-label">Country</label>
                <select asp-items="ViewBag.Country" id="Country" name="Country" class="form-control">
                    <option value="">Select Country</option>
                </select>
            </div>
            <div class="form-group">
                <label class="control-label">SubCategory Type</label>
                <select id="State" class="form-control" name="State">

                </select>
            </div>
            <br />
            <br />
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>


@if (ViewBag.SelectedCountry != null)
{
    <div>
        You selected : @ViewBag.SelectedCountry <br/>
        You selected : @ViewBag.SelectedState <br />
    </div>
}

@section Scripts{
    <script>
        $(function () {
            //jquery function to be called when country dropdown changes
            $("#Country").change(function () {
                var cid = $(this).val();
                $("#State").empty();
                //call GetStates method to get states list
                $.getJSON(`/Home/GetStates?id=${cid}`, function (data) {
                    //console.log(data);
                    $.each(data, function (i, item) {
                        $("#State").append(`<option value="${item.value}">${item.text}</option>`);
                    });
                });
            })
        });
    </script>
 }

In the above razor code, we have a HTML Form, with 2 dropdown values, one is created using ViewBag, while other is empty dropdown, which is generated once Country Dropdown is changed.

Once the Country dropdown is changed, we have added jQuery code to getJSON from HomeController -> "GetStates" ActionMethod

Then JSON data is appended in the State dropdown list.

Once you will submit form using "Create" button, page will show the selected Dropdown items.

cascading-dropdownlist-in-asp-net-core-mvc

If you will build and run the above code, you will see the output as shown in the above image.

You may also like to read:

Bulk Insert in ASP.NET Core MVC using Entity Framework Core

Run or Execute Stored Procedure using EF Core

How to change port number in ASP.NET Core?

Creating GridView in ASP.NET Core MVC with Paging

How to redirect from http to https in ASP.NET Core?