Country - State - City Dropdown - Binding - Change Event using JQuery Ajax

Country - State - City Dropdown - Binding - Change Event using JQuery Ajax



Here I have created blog, how to use dropdown cascading like, country, state and city.
I have use some generic code.

To bind state and city dropdown I have used ajax call.

 Database Script
 

/****** Object:  Table [dbo].[Country]   ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Country](
 [CountryId] [uniqueidentifier] NOT NULL,
 [CountryName] [nvarchar](50) NOT NULL,
 [CountryCode] [nvarchar](5) NULL,
 [CountryPhoneCode] [nvarchar](7) NULL,
 [Status] [nvarchar](10) NOT NULL,
 [CreatedBy] [uniqueidentifier] NOT NULL,
 [CreatedDate] [datetime] NOT NULL CONSTRAINT [DF_Country_CreatedDate]  DEFAULT (getdate()),
 [UpdatedBy] [uniqueidentifier] NULL,
 [UpdatedDate] [datetime] NOT NULL CONSTRAINT [DF_Country_UpdatedDate]  DEFAULT (getdate()),
 CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED 
(
 [CountryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

/****** Object:  Table [dbo].[State]    ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[State](
 [StateId] [uniqueidentifier] NOT NULL,
 [CountryId] [uniqueidentifier] NOT NULL,
 [StateName] [nvarchar](50) NOT NULL,
 [StateCode] [nvarchar](5) NULL,
 [Status] [nvarchar](10) NOT NULL,
 [CreatedBy] [uniqueidentifier] NOT NULL,
 [CreatedDate] [datetime] NOT NULL CONSTRAINT [DF_State_CreatedDate]  DEFAULT (getdate()),
 [UpdatedBy] [uniqueidentifier] NULL,
 [UpdatedDate] [datetime] NOT NULL CONSTRAINT [DF_State_UpdatedDate]  DEFAULT (getdate()),
 CONSTRAINT [PK_QState] PRIMARY KEY CLUSTERED 
(
 [StateId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO


/****** Object:  Table [dbo].[City]   ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[City](
 [CityId] [uniqueidentifier] NOT NULL,
 [StateId] [uniqueidentifier] NOT NULL,
 [CityName] [nvarchar](50) NOT NULL,
 [CityCode] [nvarchar](5) NULL,
 [CityPhoneCode] [nvarchar](7) NULL,
 [Status] [nvarchar](10) NOT NULL,
 [CreatedBy] [uniqueidentifier] NOT NULL,
 [CreatedDate] [datetime] NOT NULL CONSTRAINT [DF_City_CreatedDate]  DEFAULT (getdate()),
 [UpdatedBy] [uniqueidentifier] NULL,
 [UpdatedDate] [datetime] NOT NULL CONSTRAINT [DF_City_UpdatedDate]  DEFAULT (getdate()),
 CONSTRAINT [PK_City] PRIMARY KEY CLUSTERED 
(
 [CityId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO


ALTER TABLE [dbo].[City]  WITH CHECK ADD  CONSTRAINT [FK_City_State] FOREIGN KEY([StateId])
REFERENCES [dbo].[State] ([StateId])
GO
ALTER TABLE [dbo].[City] CHECK CONSTRAINT [FK_City_State]
GO
ALTER TABLE [dbo].[State]  WITH CHECK ADD  CONSTRAINT [FK_State_Country] FOREIGN KEY([CountryId])
REFERENCES [dbo].[Country] ([CountryId])
GO
ALTER TABLE [dbo].[State] CHECK CONSTRAINT [FK_State_Country]
GO
ALTER TABLE [dbo].[State]  WITH CHECK ADD  CONSTRAINT [FK_State_QDevCountry] FOREIGN KEY([CountryId])
REFERENCES [dbo].[Country] ([CountryId])
GO
ALTER TABLE [dbo].[State] CHECK CONSTRAINT [FK_State_QDevCountry]
GO
/****** Object:  Table [dbo].[Users]   ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Users](
 [UserId] [uniqueidentifier] NOT NULL,
 [usertype] [nvarchar](10) NOT NULL,
 [Username] [nvarchar](50) NOT NULL,
 [Password] [nvarchar](100) NOT NULL, 
 [FirstName] [nvarchar](40) NULL,
 [LastName] [nvarchar](30) NOT NULL, 
 [AddressLine1] [nvarchar](150) NULL,
 [AddressLine2] [nvarchar](150) NULL,
 [CityId] [uniqueidentifier] NULL,
 [EmailId] [nvarchar](50) NULL,
 [MobileNumber] [nvarchar](15) NULL,
 [HomePhoneNumber] [nvarchar](15) NULL,
 [WorkPhoneNumber1] [nvarchar](15) NULL,
 [WorkPhoneNumber2] [nvarchar](15) NULL,
 [Status] [nvarchar](8) NOT NULL,
 [CreatedBy] [uniqueidentifier] NOT NULL,
 [CreatedDate] [datetime] NULL CONSTRAINT [DF_Users_CreatedDate]  DEFAULT (getdate()),
 [UpdatedBy] [uniqueidentifier] NULL,
 [UpdatedDate] [datetime] NULL CONSTRAINT [DF_Users_UpdatedDate]  DEFAULT (getdate()),
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
 [UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

 

  View Model

namespace Demo.ViewModel
{
    public class VMCountry
    {
        public System.Guid CountryId { getset; }
 
        [Required]
        [DisplayName("Country Name")]
        public string CountryName { getset; }
 
        [Required]
        [DisplayName("Country Code")]
        public string CountryCode { getset; }
        public string CountryPhoneCode { getset; }
        public string Status { getset; }
        public System.Guid CreatedBy { getset; }
        public System.DateTime CreatedDate { getset; }
        public Nullable<System.Guid> UpdatedBy { getset; }
        public System.DateTime UpdatedDate { getset; }
    }
}

namespace Demo.ViewModel
{
    public class VMState
    {
        public System.Guid StateId { getset; }
        public System.Guid CountryId { getset; }
        public string StateName { getset; }
        public string StateCode { getset; }
        public string Status { getset; }
        public System.Guid CreatedBy { getset; }
        public System.DateTime CreatedDate { getset; }
        public Nullable<System.Guid> UpdatedBy { getset; }
        public System.DateTime UpdatedDate { getset; }
 
        public List<SelectListItem> CountryList { getset; }
    }
}

namespace Demo.ViewModel
{
    public class VMCity
    {
        public System.Guid CityId { getset; }
        public System.Guid StateId { getset; }
        public string CityName { getset; }
        public string CityCode { getset; }
        public string CityPhoneCode { getset; }
        public string Status { getset; }
        public System.Guid CreatedBy { getset; }
        public System.DateTime CreatedDate { getset; }
        public Nullable<System.Guid> UpdatedBy { getset; }
        public System.DateTime UpdatedDate { getset; }
        public List<SelectListItem> CountryList { getset; }
        public List<SelectListItem> StateList { getset; }
        public System.Guid CountryId { getset; }
    }
}

 

namespace Demo.ViewModel
{
    public class VMUser
    {
        public System.Guid UserId { getset; }
 
        public string usertype { getset; }
 
        [Required]
        [DisplayName("Username")]
        public string Username { getset; }
 
        [Required]
        [DataType(DataType.Password)]
        public string Password { getset; }
        
        [Required]
        [DisplayName("First Name")]
        public string FirstName { getset; }
 
        [DisplayName("Last Name")]
        public string LastName { getset; } 
        
        public string AddressLine1 { getset; }
 
        public string AddressLine2 { getset; }
 
        public Nullable<System.Guid> CityId { getset; }
 
        [DisplayName("Email Id")]
        public string EmailId { getset; }
 
        [DisplayName("Mobile Number")]
        public string MobileNumber { getset; } 
         
        public string Status { getset; }
        public System.Guid CreatedBy { getset; }
        public Nullable<System.DateTime> CreatedDate { getset; }
        public Nullable<System.Guid> UpdatedBy { getset; }
        public Nullable<System.DateTime> UpdatedDate { getset; }
 
 
        //Extra Properties for page view
        public List<SelectListItem> CountryList { getset; }
        public List<SelectListItem> StateList { getset; }
        public List<SelectListItem> CityList { getset; }
 
        public Nullable<System.Guid> Country { getset; }
        public Nullable<System.Guid> State { getset; }
    }
}

 

 Use Automapper to map data model and view model.

namespace Demo.Business
{
    public static class AutoMapperConfig
    {
        public static void RegisterMappings()
        { 
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<VMCountryCountry>();
                cfg.CreateMap<CountryVMCountry>();
 
                cfg.CreateMap<VMStateState>();
                cfg.CreateMap<StateVMState>();
 
                cfg.CreateMap<VMCityCity>();
                cfg.CreateMap<CityVMCity>(); 
            });
 
        }
    }
}

Setup with Automapper config in global.asax

namespace Demo.Web
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        { 
            AutoMapperConfig.RegisterMappings();
            
        }
    }
}

Setup Generic class and properties.

namespace Demo.Common
{
    public class ResultResponse<T>
    {
        public bool Success { getset; } = true;
        public string Message { getset; }
        public DTResult<T> Data { getset; }
        public T Datas { getset; }
        public Dictionary<stringstring> Exceptions { getset; }
    }
 
    public class ResultResponses<T>
    {
        public bool Success { getset; } = true;
        public string Message { getset; }
        public T Data { getset; }
        public Dictionary<stringstring> Exceptions { getset; }
    }
    public class ResultResponseSingle<T>
    {
        public bool Success { getset; } = true;
        public string Message { getset; }
        public T Data { getset; }
        public Dictionary<stringstring> Exceptions { getset; }
    }
}

Business Layer

namespace Demo.Business
{
    public class BLCountry
    {        
        public static ResultResponses<List<VMCountry>> GetCountryListforDDL()
        {
            var exceptions = new Dictionary<stringstring>();
            List<VMCountry> data = new List<VMCountry>();
 
            try
            {
                AnroAppEntities db = new AnroAppEntities();
 
                var datas = db.Countries.AsQueryable().OrderBy(c=>c.CountryName).ToList();
 
                var Datas = AutoMapper.Mapper.Map<List<Country>, List<VMCountry>>(datas);
                data = Datas;
            }
            catch (SqlException sqlException)
            {
                exceptions.Add("SqlException", sqlException.Message);
            }
            catch (TaskCanceledException taskCanceledException)
            {
                exceptions.Add("TaskCanceledException", taskCanceledException.Message);
            }
            catch (Exception ex)
            {
                exceptions.Add("Exception", ex.Message);
            }
            return new ResultResponses<List<VMCountry>>
            {
                Exceptions = exceptions,
                Data = data
            };           
        } 
    }
}

namespace Demo.Business
{
    public class BLStates
    {
        public static ResultResponses<List<VMState>> GetStateListforDDL(string CountryId)
        {
            var exceptions = new Dictionary<stringstring>();
            
            List<VMState> Data = new List<VMState>();
 
            try
            {
                AnroAppEntities db = new AnroAppEntities();
 
                Guid countryId = new Guid(CountryId);
 
                var datas = db.States.AsQueryable().Where(a => a.CountryId == countryId).OrderBy(c => c.StateName).ToList();
                
                var Datas = AutoMapper.Mapper.Map<List<State>, List<VMState>>(datas);
                Data = Datas;                
 
            }
            catch (SqlException sqlException)
            {
                exceptions.Add("SqlException", sqlException.Message);
            }
            catch (TaskCanceledException taskCanceledException)
            {
                exceptions.Add("TaskCanceledException", taskCanceledException.Message);
            }
            catch (Exception ex)
            {
                exceptions.Add("Exception", ex.Message);
            }
            return new ResultResponses<List<VMState>>
            {
                Exceptions = exceptions,
                Data = Data
            }; 
        } 
    }
}

namespace Demo.Business
{
    public class BLCity
    {
        public static ResultResponses<List<VMCity>> GetCityListforDDL(string StateId)
        {
            var exceptions = new Dictionary<stringstring>();
 
            List<VMCity> Data = new List<VMCity>();
 
            try
            {
                AnroAppEntities db = new AnroAppEntities();
 
                Guid stateId = new Guid(StateId);
 
                var datas = db.Cities.AsQueryable().Where(a => a.StateId == stateId).OrderBy(c => c.CityName).ToList();
 
                var Datas = AutoMapper.Mapper.Map<List<City>, List<VMCity>>(datas);
                Data = Datas;
 
            }
            catch (SqlException sqlException)
            {
                exceptions.Add("SqlException", sqlException.Message);
            }
            catch (TaskCanceledException taskCanceledException)
            {
                exceptions.Add("TaskCanceledException", taskCanceledException.Message);
            }
            catch (Exception ex)
            {
                exceptions.Add("Exception", ex.Message);
            }
            return new ResultResponses<List<VMCity>>
            {
                Exceptions = exceptions,
                Data = Data
            }; 
        } 
    }
}

 

namespace Demo.Business
{
    public class BLUsers
    { 
        public static ResultResponse<string> Save(VMUser objData, string AddorUpdate)
        {
            string returnMessage = "";
            var exceptions = new Dictionary<stringstring>();
 
            try
            {
                using (var db = new AnroAppEntities())
                {
                    var user = AutoMapper.Mapper.Map<VMUserUser>(objData);
 
                    if (AddorUpdate == "add")
                        db.Users.Add(user);
                    else
                        db.Entry(user).State = System.Data.Entity.EntityState.Modified;
 
 
                    var i = db.SaveChanges();
                    if (i == 1)
                        returnMessage = "success";
                    else
                        returnMessage = "Something wrong";
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
            {
                Exception raise = dbEx;
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        string message = string.Format("{0}:{1}",
                            validationErrors.Entry.Entity.ToString(),
                            validationError.ErrorMessage);
                        raise = new InvalidOperationException(message, raise);
                    }
                }
                throw raise;
            }
            catch (SqlException sqlException)
            {
                exceptions.Add("SqlException", sqlException.Message);
            }
            catch (TaskCanceledException taskCanceledException)
            {
                exceptions.Add("TaskCanceledException", taskCanceledException.Message);
            }
            catch (Exception ex)
            {
                exceptions.Add("Exception", ex.Message);
            }
            return new ResultResponse<string>
            {
                Exceptions = exceptions,
                Message = returnMessage
            };
        } 
    }
}

Common Controller
using Demo.Business;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
 
namespace Demo.Web.Controllers
{
    public class CommonController : Controller
    {
 
        public static List<SelectListItem> BindCountryList()
        {
            List<SelectListItem> items = new List<SelectListItem>();
            var list = BLCountry.GetCountryListforDDL();
            var statuslist = list.Data.ToList();
            items = statuslist.Select(a => new SelectListItem
            {
                Text = a.CountryName,
                Value = a.CountryId.ToString()
            }).ToList();
            return items;
        }
 
        public static List<SelectListItem> BindStateList(string id)
        {
            List<SelectListItem> items = new List<SelectListItem>();
            var list = BLStates.GetStateListforDDL(id);
            var statuslist = list.Data.ToList();
            items = statuslist.Select(a => new SelectListItem
            {
                Text = a.StateName,
                Value = a.StateId.ToString()
            }).ToList();
            return items;
        }
 
        public static List<SelectListItem> BindCityList(string id)
        {
            List<SelectListItem> items = new List<SelectListItem>();
            var list = BLCity.GetCityListforDDL(id);
            var statuslist = list.Data.ToList();
            items = statuslist.Select(a => new SelectListItem
            {
                Text = a.CityName,
                Value = a.StateId.ToString()
            }).ToList();
            return items;
        }
 
        public JsonResult GetStates(string id)
        {
            List<SelectListItem> datas = new List<SelectListItem>();
            var list = BLStates.GetStateListforDDL(id).Data.ToList(); 
            
            datas = list.Select(a => new SelectListItem
            {
                Text = a.StateName,
                Value = a.StateId.ToString()
            }).ToList();
            datas.Insert(0, new SelectListItem { Text = "Select State", Value = "select" });
            return Json(new SelectList(datas, "Value""Text"));
        }
 
        public JsonResult GetCity(string id)
        {
            List<SelectListItem> datas = new List<SelectListItem>();
            var list = BLCity.GetCityListforDDL(id).Data.ToList();
 
            datas = list.Select(a => new SelectListItem
            {
                Text = a.CityName,
                Value = a.CityId.ToString()
            }).ToList();
            datas.Insert(0, new SelectListItem { Text = "Select City", Value = "select" });
            return Json(new SelectList(datas, "Value""Text"));
        }
 
        public ActionResult refreshdata()
        {
            return Json(new { message = "success" }, JsonRequestBehavior.AllowGet);
        }
    }
}

User Controller with Register Action and Save action

namespace Demo.Web.Controllers
{
    public class UserController : Controller
    {         
        
        public ActionResult Register()
        {
            VMUser model = new VMUser();
            model.CountryList = CommonController.BindCountryList();
 
 
            model.CountryList = CommonController.BindCountryList();
            var countryid = model.CountryList.Where(a => a.Text.ToLower() == "india").FirstOrDefault().Value;
            
 
            model.Country = countryid != null ? new Guid(countryid) : Guid.NewGuid();
 
            model.StateList = CommonController.BindStateList(countryid != null ? countryid : Guid.NewGuid().ToString());
            var statedata = model.StateList.Where(s => s.Text.ToLower() == "gujarat").FirstOrDefault();
            var stateid = statedata != null ? statedata.Value : null;
            model.State = stateid != null ? new Guid(stateid) : Guid.NewGuid();
            
 
            model.CityList = CommonController.BindCityList(stateid != null ? stateid : Guid.NewGuid().ToString());
            var citydata = model.CityList.Where(s => s.Text.ToLower() == "ahmedabad").FirstOrDefault();
            var cityid = citydata != null ? citydata.Value : null;
            model.CityId = cityid != null ? new Guid(cityid) : Guid.NewGuid();
            
            
 
            return View(model);
        }
 
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(VMUser model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    model.UserId = Guid.NewGuid();
                    model.Status = "Active";
                    model.CreatedBy = Guid.NewGuid();
                    model.CreatedDate = DateTime.Now;
                    model.UpdatedBy = null;
                    model.UpdatedDate = DateTime.Now;
 
                    var data = BLUser.Save(model, "add");
                    if (data.Exceptions.Count > 0)
                    {
                        string error = "";
                        foreach (var keyValuePair in data.Exceptions)
                        {
                            error += keyValuePair.Value;
                        }
                        ModelState.AddModelError("", error);
                    }
 
                    return RedirectToAction("Index");
                }
 
                return View(model);
            }
            catch (Exception ex)
            {                
                ModelState.AddModelError("", ex.Message);
                return View(model);
            }
        }
    }
}

View page

@model Demo.ViewModel.VMUser
@{
    ViewBag.Title = "Register";
}
 
<section class="content">
    <div class="box">
        <div class="box-header with-border">
            <h3 class="box-title">User - Register</h3>
        </div>
        <!-- /.box-header -->
        <div class="box-body">
            <div class="col-md-8">
                @using (Html.BeginForm())
                {
                    @Html.AntiForgeryToken()
 
                    <div>
                        @Html.ValidationSummary(true""new { @class = "text-danger" })
                        
                        <div class="row">
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.Username, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.Password, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.FirstName, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.LastName, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.EmailId, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.EmailId, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.EmailId, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.MobileNumber, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.MobileNumber, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.MobileNumber, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                        </div>
 
                        <div class="row">
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.AddressLine1, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.AddressLine1, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.AddressLine1, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.AddressLine2, htmlAttributes: new { @class = "control-label" })
                                    @Html.EditorFor(model => model.AddressLine2, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.AddressLine2, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                        </div>
 
                        <div class="row">
                            <div class="col-md-4">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.Country, htmlAttributes: new { @class = "control-label" })
                                    @Html.DropDownListFor(model => model.Country, Model.CountryList, "Please select a Country", htmlAttributes: new { @class = "form-control select2", @id = "countryid" })
                                    @Html.ValidationMessageFor(model => model.Country, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                            <div class="col-md-4">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label" })
                                    @Html.DropDownListFor(model => model.State, Model.StateList, "Please select a State", htmlAttributes: new { @class = "form-control select2", @id = "stateid" })
                                    @Html.ValidationMessageFor(model => model.State, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                            <div class="col-md-4">
                                <div class="form-group">
                                    @Html.LabelFor(model => model.CityId, htmlAttributes: new { @class = "control-label" })
                                    @Html.DropDownListFor(model => model.CityId, Model.CityList, "Please select a City", htmlAttributes: new { @class = "form-control select2", @id = "cityid" })
                                    @Html.ValidationMessageFor(model => model.CityId, ""new { @class = "text-danger validation-msg " })
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-10">
                                <div class="form-group">
                                    <input type="submit" value="Create" class="btn btn-primary" />
                                    @Html.ActionLink("Back to List""Index"nullnew { @class = "btn btn-default" })
                                </div>
                            </div>
                        </div>
                    </div>
                }
 
            </div>
        </div> 
    </div>
</section>
 
<script src="~/Content/CustomJS/User.js"></script>

User.js - Ajax call

var sitename = '/demo.web';
 
$(document).ready(function () {
   
    //Country Dropdownlist Selectedchange event
    $("#countryid").change(function () {
        $("#stateid").empty();
        $("#cityid").empty();
        $.ajax({
            type: 'POST',
            url: sitename + '/Common/GetStates',
            dataType: 'json',
            data: { id: $("#countryid").val() },
            success: function (states) {
                $.each(states, function (i, state) {
                    $("#stateid").append('<option value="' + state.Value + '">' +
                            state.Text + '</option>');
                });
 
                $("#cityid").append('<option value="select">Select City</option>');
            },
            error: function (ex) {
                alert('Failed to retrieve states.' + ex);
            }
        });
        return false;
    }); 
 
    //State Dropdownlist Selectedchange event
    $("#stateid").change(function () {
        $("#cityid").empty();
        $.ajax({
            type: 'POST',
            url: sitename + '/Common/GetCity',
            dataType: 'json',
            data: { id: $("#stateid").val() },
            success: function (states) {
                $.each(states, function (i, state) {
                    $("#cityid").append('<option value="' + state.Value + '">' +
                            state.Text + '</option>');
                });
            },
            error: function (ex) {
                alert('Failed to retrieve states.' + ex);
            }
        });
        return false;
    }); 
});

Finally you will get below out put for dropdown

 

Enjoy !!!

:)