Cascading Dropdown List By Country, State And City Using MVC, Web API And Angular

Today, in this article, I will explain how to perform Cascading dropdown list using MVC, Web API, and AngularJS. Here, I am using three tables: Country, State, and City respectively. If we select a country, it should display country-related states and when we select a state, then it should display state-related cities. Finally, here, we will use MVC, Web, AngularJS, and SQL Server. I have completed the same already using jQuery. You can find the article at this link. So now, let us see step by step.

Step 1

We have to create three tables: Country, State, and City.
ASP.NET

Step 2

Now, we will create an MVC application but we create two projects here -- Web API project to create service, and MVC Project for consuming the service. So now, we will add the first MVC project and then we will add Web API Project.

Just go through File->New ->Web application ->select MVC ->OK.
ASP.NET
Step 3

Now, let us add  tables in Web API project using Entity framework. So for this, go to Model folder -> Right click -> Add -> New item -> ADO.NET Entity Data Model -> click Add -> select database first approach->Click Next.

Select New Connection and give the connection details, then select database ->Click OK.

Choose tables and click OK.

ASP.NET

Step 4

Now we write the logic for bind Country, State and City.  So I create a folder, Business Logic, and take a class CascadingLogic.cs, and write the logic:

ASP.NET

  1. public class CascadingLogic  
  2.  {  
  3.      JobPortalEntities dbEntity = new JobPortalEntities();  
  4.   
  5.      public List<Country> BindCountry()  
  6.      {  
  7.         this.dbEntity.Configuration.ProxyCreationEnabled = false;  
  8.   
  9.          List<Country> lstCountry = new List<Country>();  
  10.          try  
  11.          {  
  12.              lstCountry = dbEntity.Countries.ToList();  
  13.          }  
  14.          catch (Exception ex)  
  15.          {  
  16.              ex.ToString();  
  17.          }  
  18.          return lstCountry;  
  19.      }  
  20.   
  21.      public List<State> BindState(int countryId)  
  22.      {  
  23.          List<State> lstState = new List<State>();  
  24.          try  
  25.          {  
  26.              this.dbEntity.Configuration.ProxyCreationEnabled = false;  
  27.   
  28.              lstState = dbEntity.States.Where(a => a.CountryId == countryId).ToList();  
  29.          }  
  30.          catch (Exception ex)  
  31.          {  
  32.              ex.ToString();  
  33.          }  
  34.          return lstState;  
  35.      }  
  36.   
  37.      public List<City> BindCity(int stateId)  
  38.      {  
  39.          List<City> lstCity = new List<City>();  
  40.          try  
  41.          {  
  42.              this.dbEntity.Configuration.ProxyCreationEnabled = false;  
  43.   
  44.              lstCity = dbEntity.Cities.Where(a => a.StateId == stateId).ToList();  
  45.          }  
  46.          catch (Exception ex)  
  47.          {  
  48.              ex.ToString();  
  49.          }  
  50.          return lstCity;  
  51.      }  
  52.  }  

After that, we will add an API Controller.

ASP.NET

Create an API method and call the methods one by one.

  1. [RoutePrefix("api/Cascading")]  
  2.   public class CascadingDetailsController : ApiController  
  3.   {  
  4.       CascadingLogic objCasc = new CascadingLogic();  
  5.       [HttpGet]  
  6.       [Route("CountryDetails")]  
  7.       public List<Country> BindCountryDetails()  
  8.       {  
  9.   
  10.   
  11.           List<Country> countryDetail = new List<Country>();  
  12.           try  
  13.           {  
  14.               countryDetail = objCasc.BindCountry();  
  15.           }  
  16.           catch (ApplicationException ex)  
  17.           {  
  18.               throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = ex.Message });  
  19.           }  
  20.           catch (Exception ex)  
  21.           {  
  22.               throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadGateway, ReasonPhrase = ex.Message });  
  23.           }  
  24.   
  25.           return countryDetail;  
  26.       }  
  27.   
  28.       [HttpGet]  
  29.       [Route("StateDetails")]  
  30.       public List<State> BindStateDetails(int CountryId)  
  31.       {  
  32.   
  33.           List<State> stateDetail = new List<State>();  
  34.           try  
  35.           {  
  36.               stateDetail = objCasc.BindState(CountryId);  
  37.           }  
  38.           catch (ApplicationException ex)  
  39.           {  
  40.               throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = ex.Message });  
  41.           }  
  42.           catch (Exception ex)  
  43.           {  
  44.               throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadGateway, ReasonPhrase = ex.Message });  
  45.           }  
  46.   
  47.           return stateDetail;  
  48.       }  
  49.   
  50.       [HttpGet]  
  51.       [Route("CityDetails")]  
  52.       public List<City> BindCityDetails(int stateId)  
  53.       {  
  54.           List<City> cityDetail = new List<City>();  
  55.           try  
  56.           {  
  57.               cityDetail = objCasc.BindCity(stateId);  
  58.           }  
  59.           catch (ApplicationException ex)  
  60.           {  
  61.               throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = ex.Message });  
  62.           }  
  63.           catch (Exception ex)  
  64.           {  
  65.               throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadGateway, ReasonPhrase = ex.Message });  
  66.           }  
  67.   
  68.           return cityDetail;  
  69.       }  
  70.   
  71.   }  

Step 5

Now, let us go to MVC project and add a Controller.

ASP.NET

After that, create an action method for View and View page.

  1. public ActionResult Details()  
  2.         {  
  3.             return View();  
  4.         }  

NOTE

Here, we will not consume the API service using server-side but directly use the client-side.

Step 6

Here, we will use Angular js for consuming the service of Country, State and City. So for that, first we have to download AngularJS library. We have downloaded the same using NuGet Package Manager.

ASP.NET

After that, we added three JavaScript files - App.js for registering the module; Service.js for writing the factory method; and Cascad.js file for writing the Controller code.

ASP.NET

In App.js, write the below code.

  1. var app = angular.module('MyApp', []);  

In Service.js, write the below code.

  1. app.factory('CommonUrlService'function ($http) {  
  2.     var fac = {};  
  3.   
  4.     //For Country Bind    
  5.     fac.GetCountry = function () {  
  6.         return $http.get('http://localhost:54188/api/Cascading/CountryDetails');  
  7.     };  
  8.   
  9.     //For State Bind  
  10.     fac.GetState = function (CountryId) {  
  11.         return $http.get('http://localhost:54188/api/Cascading/StateDetails/' + CountryId);  
  12.     };  
  13.   
  14.     //For City Bind  
  15.     fac.GetCity = function (stateId) {  
  16.         return $http.get('http://localhost:54188/api/Cascading/CityDetails/' + stateId);  
  17.     };  
  18.    
  19.     return fac;  
  20. });  

Then, in Cascad.js file, write the below code.

  1. app.controller('CascadController'function ($scope, CommonUrlService) {  
  2.      
  3.     $scope.CountryList = {};  
  4.     
  5.     $scope.CityList = {};  
  6.     $scope.StateList = {};  
  7.   
  8.     $scope.CountryText = "Select Country..";  
  9.   
  10.     CommonUrlService.GetCountry().then(function (d) {  
  11.   
  12.         $scope.CountryList = d.data;  
  13.     });  
  14.   
  15.     $scope.GetState = function () {  
  16.       
  17.         $scope.StateText = "Please Wait...";  
  18.         CommonUrlService.GetState($scope.CountryId).then(function (d) {  
  19.             $scope.StateList = d.data;  
  20.             $scope.StateText = "Select State";  
  21.         }, function (error) {  
  22.             alert('Error!');  
  23.         });  
  24.     }  
  25.   
  26.     $scope.GetCity = function () {  
  27.         $scope.CityText = "Please Wait...";  
  28.   
  29.         CommonUrlService.GetCity($scope.StateId).then(function (d) {  
  30.             $scope.CityList = d.data;  
  31.             $scope.CityText = "Select City";  
  32.         }, function (error) {  
  33.             alert('Error!');  
  34.         });  
  35.     }  
  36.   
  37. });  

Okay! Custom Angular logic is completed now. We have to design the HTML of the View page now.

And register the ng-app directory and ng-controller directory.

  1. <script src="~/Scripts/angular.js"></script>  
  2. <script src="~/Scripts/Angulajs/App.js"></script>  
  3. <script src="~/Scripts/Angulajs/Cascad.js"></script>  
  4. <script src="~/Scripts/Angulajs/Service.js"></script>  
  5.   
  6.   
  7. <h1>Cascading Dropdown List of Country, State and City</h1>  
  8. <hr />  
  9. <br />  
  10. <div class="row" ng-app="MyApp">  
  11.     <div class="col-lg-3"></div>  
  12.     <div class="col-lg-6" ng-controller="CascadController">  
  13.   
  14.         <div class="form-group">  
  15.             <label class="col-md-4 control-label">Country Name</label>  
  16.             <div class="col-md-6">  
  17.                 <select class="form-control" id="ddlCountry" ng-model="CountryId" ng-options="C.CountryId as C.CountryName for C in CountryList" ng-change="GetState()">  
  18.                 <option value="{{CountryText}}">Select Country</option>  
  19.                 </select><br />  
  20.             </div>  
  21.         </div>  
  22.   
  23.         <div class="form-group">  
  24.             <label class="col-md-4 control-label">State Name</label>  
  25.             <div class="col-md-6">  
  26.                 <select class="form-control" id="ddlState" ng-model="StateId" ng-options="S.StateId as S.StateName for S in StateList" ng-change="GetCity()">  
  27.                     <option>{{StateText}}</option>  
  28.                 </select>  
  29.                 <br />  
  30.   
  31.             </div>  
  32.         </div>  
  33.         <br />  
  34.         <div class="form-group">  
  35.             <label class="col-md-4 control-label">City Name</label>  
  36.             <div class="col-md-6">  
  37.                 <select class="form-control" id="ddlCity" ng-model="CityId" ng-options="C.CityId as C.CityName for C in CityList">  
  38.                     <option>{{CityText}}</option>  
  39.                 </select>  
  40.   
  41.             </div>  
  42.         </div>  
  43.     </div>  
  44.     <div class="col-lg-3"></div>  
  45. </div>  

Output Design

ASP.NET

Run the project, however, we have to run both projects at one time so for this, so we have to set some changes. Right-click on the solution project and go to properties. Here, check the Multiple Startup Projects option and click the Apply button.

ASP.NET

Now, we see an output with an unexpected error.

ASP.NET
This error is called CORS. So first, we have to know what CORS is and how to resolve this problem.

According to Wikipedia,

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served.

For more details, click this link.

Now, let us learn how to resolve this problem.

So for this, we have to download CORS in Web API project. Go to NuGet Package Manager and download the following file.

MVC

After that, goto App_Start folder in Web API project and then WebApiConfig.cs class. Here, modify the Register method with the below code.

  1. var cors = new EnableCorsAttribute("*""*""*");// origins, headers, methods  
  2. config.EnableCors(cors);  

Now, save changes and run the project to see the final output.

Select a country

MVC

Select a state

MVC

Thanks! I hope this article was helpful.