Convention Routing in ASP.NET MVC 5

In this article, we will learn about Convention Routing in ASP.NET MVC 5.

Introduction

 
In ASP.NET MVC, when a user requests any webpage, the requested URL should match with the URL pattern defined in RegisterRoutes method of RouteConfig class. If the URL doesn't match with the pattern, then the user will be displayed with an error message.

If the user doesn't provide the action method name in the URL, then by default Index Action Method will be executed. Similarly, if the user doesn't provide Controller name and the Action Method name in the URL, then the default Controller and default Action Method will be executed.
 
Whenever the user creates an MVC application, by default RegisterRoutes method will come with the following code.
  1. routes.MapRoute(  
  2. name: "Default",  
  3. url: "{controller}/{action}/{id}",  
  4. defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }  
  5. );  
Above, the user needs to provide the URL as the Controller Name/ Action Method Name and a Parameter Value like below, localhost:40962/Employee/Details/1. To handle this request we should have Details Action Method in EmployeeController.
  1. public ActionResult Details(int employeeId)  
  2. {  
  3. return View();  
  4. }  
If the user provides an employeeId parameter in the Details Action Method that doesn't match with the above URL pattern, the request cannot be handled with the Controller and its Action Method. Instead we will receive an error.
 
Instead of using the default routing pattern, we can write our own routing. This is nothing but Convention Routing. In the below code we have two convention routing or
user defined routing and one default routing. 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6. using System.Web.Routing;  
  7.   
  8. namespace ConventionRouting  
  9. {  
  10.     public class RouteConfig  
  11.     {  
  12.         public static void RegisterRoutes(RouteCollection routes)  
  13.         {  
  14.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  15.   
  16.             routes.MapRoute(  
  17.                 "GetEmployeeById",  
  18.                 "Employee/GetEmployeeInfo/{employeeId}",  
  19.                 new {Controller="Employee",action ="GetEmployeeByEId"},  
  20.                 new {employeeId = @"\d{4}"}  
  21.                 );  
  22.   
  23.             routes.MapRoute(  
  24.                 "GetEmployeeByDeptId",  
  25.                 "Employee/GetEmployeeInfoByDept/{departmentId}",  
  26.                 new {controller = "Employee", action = "GetEmployeeByDId"},  
  27.                 new {departmentId = @"\d{4}"}  
  28.                 );  
  29.   
  30.             routes.MapRoute(  
  31.                 name: "Default",  
  32.                 url: "{controller}/{action}/{id}",  
  33.                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }  
  34.             );  
  35.         }  
  36.     }  
  37. }  
 
In the first routing, we have the default name set as "GetEmployeeById", the URL as "Employee/GetEmployeeInfo/{employeeId}", the Controller Name as Employee, Action Method as "GetEmployeeByEId" and Constraints as employeeId=@"\d{4}".
 
From the above Convention Routing, we have provided the URL as "Employee/GetEmployeeInfo/{employeeId}", whenever the user navigates to this URL by passing the
value then the GetEmployeeByEId Action Method is executed. Here, the GetEmployeeByEId Action Method parameter name and routing URL pattern parameter name should be the same. We have given constraint name as employeeId that should contain 4 digits.
 
In the second routing, we have the default name set as "GetEmployeeByDeptId", the URL as "Employee/GetEmployeeInfoByDept/{departmentId}", Controller Name as Employee, the ActionMethod as "GetEmployeeByDId" and Constraints as departmentId = @"\d{4}".
 
From the above Convention Routing, we have provided the URL as "Employee/GetEmployeeInfoByDept/{departmentId}", whenever the user navigates to this URL by passing the value then "GetEmployeeByDId" Action Method is executed. Here "GetEmployeeByDId" Action Method parameter name and the routing URL pattern parameter name should be the same. We have given constraint name as departmentId that should contain 4 digits.
 
If GetEmployeeByEId / GetEmployeeByDId Action Method parameter name doesn't match with the routing URL pattern or employeeId / departmentId contains less than 4 digits, then the user will be displayed with an error message.
 

Convention Routing in ASP.NET MVC 5 

 
In order to understand convention-based routing, I have created an ASP.NET MVC application.
 
I am using Visual Studio 2019 community edition to create a sample project, you can use any version of your choice.
 
Step 1 - Open Visual Studio 2019 and click on Create a new project on the bottom right, as shown below:
 
 
 
Step 2 - Search ASP.NET Web Application in the above-provided textbox and click on the template. Then, click on the Next button as shown below:
 
 
 
Step 3 - Provide the Project name as you wish, I have used the project name ConventionRouting. Click on Create button.
 
Step 4 - Select the MVC template and click on the Create button. With this, a new MVC project is Created.
 
Once the ASP.NET 5 Application is created, we need to Create a Model to use in our application. In this example, I will assign the object with some hardcoded values.
 
In order to create a Model, right-click on the Models folder then click on Add. Select the class template and give the name as Employee.cs, then click on the Add button.
 
With this, Employee.cs Model will be created in the Models folder.
 
Open the Employee.cs file and paste the properties as shown below  
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Linq;  
  5. using System.Web;  
  6.   
  7. namespace ConventionRouting.Models  
  8. {  
  9.     public class Employee  
  10.     {  
  11.         [DisplayName("Employee Id")]  
  12.         public int EmployeeId { getset; }  
  13.         [DisplayName("Employee Name")]  
  14.         public string EmployeeName { getset; }  
  15.         [DisplayName("Employee Designation")]  
  16.         public string EmployeeDesignation { getset; }  
  17.         [DisplayName("Date Of Joining")]  
  18.         public string DateOfJoining { getset; }  
  19.         [DisplayName("Employee Phone")]  
  20.         public int EmployeePhone { getset; }  
  21.         [DisplayName("Employee Gender")]  
  22.         public string EmployeeGender { getset; }  
  23.         [DisplayName("City")]  
  24.         public string City { getset; }  
  25.         [DisplayName("Project")]  
  26.         public string Project { getset; }  
  27.         [DisplayName("Company Name")]  
  28.         public string CompanyName { getset; }  
  29.         [DisplayName("Department Name")]  
  30.         public string DepartmentName { getset; }  
  31.         [DisplayName("Department Id")]  
  32.         public int DepartmentId { getset; }            
  33.     }  
  34. }  
In order to create a EmployeeController, right click on Controller's folder, click on Add and click on Controller, with this Add Scaffold template will be opened. In this
select MVC 5 Controller - empty and click on Add button. In the Add Controller window, give the Controller name as EmployeeController and click on the Add button. A 
EmployeeController will be created in the Controllers folder.
 
Now open the EmployeeController.cs class file and paste the below code. 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6. using ConventionRouting.Models;  
  7.   
  8. namespace ConventionRouting.Controllers  
  9. {  
  10.     public class EmployeeController : Controller  
  11.     {  
  12.         List<Employee> listEmployee = new List<Employee>();  
  13.   
  14.         // GET: Employee  
  15.         public ActionResult GetEmployeeByEId(int employeeId)  
  16.         {  
  17.             AssigningValues();  
  18.             Employee employees = (Employee) listEmployee.Where(x => x.EmployeeId == employeeId).ToList().SingleOrDefault();  
  19.               
  20.             return View(employees);  
  21.         }  
  22.   
  23.         public ActionResult GetEmployeeByDId(int departmentId)  
  24.         {  
  25.             AssigningValues();  
  26.             List<Employee> employeeByDept = listEmployee.Where(x => x.DepartmentId == departmentId).ToList();  
  27.             return View(employeeByDept);  
  28.         }  
  29.   
  30.   
  31.         public void AssigningValues()  
  32.         {  
  33.             listEmployee.Add(new Employee()  
  34.             {  
  35.                 EmployeeId = 1001,  
  36.                 EmployeeName = "Khaja",  
  37.                 EmployeeDesignation = "SE",  
  38.                 DateOfJoining = "22/05/2015",  
  39.                 EmployeePhone = 806980474,  
  40.                 EmployeeGender = "Male",  
  41.                 City = "Hyderabad",  
  42.                 Project = "AILabz",  
  43.                 CompanyName = "ValueLabs",  
  44.                 DepartmentName = "Testing",  
  45.                 DepartmentId = 1700  
  46.             });  
  47.   
  48.             listEmployee.Add(new Employee()  
  49.             {  
  50.                 EmployeeId = 1002,  
  51.                 EmployeeName = "Vijay",  
  52.                 EmployeeDesignation = "S.SE",  
  53.                 DateOfJoining = "10/05/2013",  
  54.                 EmployeePhone = 907846532,  
  55.                 EmployeeGender = "Male",  
  56.                 City = "Hyderabad",  
  57.                 Project = "AutomationTool",  
  58.                 CompanyName = "Accenture",  
  59.                 DepartmentName = "Quality Analyst",  
  60.                 DepartmentId = 1701  
  61.             });  
  62.   
  63.             listEmployee.Add(new Employee()  
  64.             {  
  65.                 EmployeeId = 1003,  
  66.                 EmployeeName = "Ganesh",  
  67.                 EmployeeDesignation = "TeamLead",  
  68.                 DateOfJoining = "01/10/2012",  
  69.                 EmployeePhone = 798534120,  
  70.                 EmployeeGender = "Male",  
  71.                 City = "Bangalore",  
  72.                 Project = "AzureDevOps",  
  73.                 CompanyName = "Cognizant",  
  74.                 DepartmentName = "Quality Analyst",  
  75.                 DepartmentId = 1701  
  76.             });  
  77.   
  78.             listEmployee.Add(new Employee()  
  79.             {  
  80.                 EmployeeId = 1004,  
  81.                 EmployeeName = "Pavan",  
  82.                 EmployeeDesignation = "Manager",  
  83.                 DateOfJoining = "01/10/2012",  
  84.                 EmployeePhone = 798534120,  
  85.                 EmployeeGender = "Male",  
  86.                 City = "Bangalore",  
  87.                 Project = "AzureDevOps",  
  88.                 CompanyName = "Cognizant",  
  89.                 DepartmentName = "Development",  
  90.                 DepartmentId = 1702  
  91.             });  
  92.         }  
  93.     }  
  94. }   
Here we have two Action Methods, GetEmployeeByEId and GetEmployeeByDId. In the first Action Method, I am filtering through a list of employees by employeeId. In the second Action Method, I am filtering a list of employees by departmentId.
 
In order to Create a View for the GetEmployeeByEId Action Method, right-click on GetEmployeeByEId Action Method, click on Add View and click on Add. A GetEmployeeByEId.cshtml file will be created.
 
Similarly, in order to Create a View for GetEmployeeByDId Action Method, right-click on GetEmployeeByDId Action Method, click on Add View and click on Add.
GetEmployeeByDId.cshtml file will be created.
 
Open the GetEmployeeByEId.cshtml file and paste the below code:
  1. @model ConventionRouting.Models.Employee  
  2. @{  
  3.     ViewBag.Title = "GetEmployeeByEId";  
  4. }    
  5. <h2>GetEmployeeByEId</h2>   
  6. <hr>    
  7. <h3>Employee Information Using Convention Routing</h3>  
  8. <table>  
  9.     <tr>  
  10.         <th>@Html.DisplayNameFor(x => x.EmployeeId)</th>  
  11.         <th>@Html.DisplayNameFor(x => x.EmployeeName)</th>  
  12.         <th>@Html.DisplayNameFor(x => x.EmployeeDesignation)</th>  
  13.         <th>@Html.DisplayNameFor(x => x.DateOfJoining)</th>  
  14.         <th>@Html.DisplayNameFor(x => x.EmployeePhone)</th>  
  15.         <th>@Html.DisplayNameFor(x => x.EmployeeGender)</th>  
  16.         <th>@Html.DisplayNameFor(x => x.City)</th>  
  17.         <th>@Html.DisplayNameFor(x => x.Project)</th>  
  18.         <th>@Html.DisplayNameFor(x => x.CompanyName)</th>  
  19.         <th>@Html.DisplayNameFor(x => x.DepartmentName)</th>  
  20.         <th>@Html.DisplayNameFor(x => x.DepartmentId)</th>  
  21.   
  22.     </tr>  
  23.   
  24.     <tr>  
  25.         <td>@Html.DisplayFor(x => x.EmployeeId)</td>  
  26.         <td>@Html.DisplayFor(x => x.EmployeeName)</td>  
  27.         <td>@Html.DisplayFor(x => x.EmployeeDesignation)</td>  
  28.         <td>@Html.DisplayFor(x => x.DateOfJoining)</td>  
  29.         <td>@Html.DisplayFor(x => x.EmployeePhone)</td>  
  30.         <td>@Html.DisplayFor(x => x.EmployeeGender)</td>  
  31.         <td>@Html.DisplayFor(x => x.City)</td>  
  32.         <td>@Html.DisplayFor(x => x.Project)</td>  
  33.         <td>@Html.DisplayFor(x => x.CompanyName)</td>  
  34.         <td>@Html.DisplayFor(x => x.DepartmentName)</td>  
  35.         <td>@Html.DisplayFor(x => x.DepartmentId)</td>    
  36.     </tr>    
  37. </table>  
  38.  
  39. <style>  
  40.     table {  
  41.         font-family: arial, sans-serif;  
  42.         border-collapse: collapse;  
  43.         width: 100%;  
  44.     }  
  45.   
  46.     td, th {  
  47.         border: 1px solid #dddddd;  
  48.         text-align: left;  
  49.         padding: 4px;  
  50.     }  
  51. </style>   
Open GetEmployeeByDId.cshtml file and paste the below code:
  1. @model IEnumerable<ConventionRouting.Models.Employee>  
  2.   
  3. @{  
  4.     ViewBag.Title = "GetEmployeeByDId";  
  5. }  
  6.   
  7. <h2>GetEmployeeByDId</h2>  
  8.   
  9. <hr>  
  10.   
  11. <h3>Employee Information Using Convention Routing</h3>  
  12. <table>  
  13.     <tr>  
  14.         <th>@Html.DisplayNameFor(x => x.EmployeeId)</th>  
  15.         <th>@Html.DisplayNameFor(x => x.EmployeeName)</th>  
  16.         <th>@Html.DisplayNameFor(x => x.EmployeeDesignation)</th>  
  17.         <th>@Html.DisplayNameFor(x => x.DateOfJoining)</th>  
  18.         <th>@Html.DisplayNameFor(x => x.EmployeePhone)</th>  
  19.         <th>@Html.DisplayNameFor(x => x.EmployeeGender)</th>  
  20.         <th>@Html.DisplayNameFor(x => x.City)</th>  
  21.         <th>@Html.DisplayNameFor(x => x.Project)</th>  
  22.         <th>@Html.DisplayNameFor(x => x.CompanyName)</th>  
  23.         <th>@Html.DisplayNameFor(x => x.DepartmentName)</th>  
  24.         <th>@Html.DisplayNameFor(x => x.DepartmentId)</th>  
  25.   
  26.     </tr>  
  27.       
  28.     @foreach (Employee employee in @Model)  
  29.     {  
  30.         <tr>  
  31.             <td>@Html.DisplayFor(x => employee.EmployeeId)</td>  
  32.             <td>@Html.DisplayFor(x => employee.EmployeeName)</td>  
  33.             <td>@Html.DisplayFor(x => employee.EmployeeDesignation)</td>  
  34.             <td>@Html.DisplayFor(x => employee.DateOfJoining)</td>  
  35.             <td>@Html.DisplayFor(x => employee.EmployeePhone)</td>  
  36.             <td>@Html.DisplayFor(x => employee.EmployeeGender)</td>  
  37.             <td>@Html.DisplayFor(x => employee.City)</td>  
  38.             <td>@Html.DisplayFor(x => employee.Project)</td>  
  39.             <td>@Html.DisplayFor(x => employee.CompanyName)</td>  
  40.             <td>@Html.DisplayFor(x => employee.DepartmentName)</td>  
  41.             <td>@Html.DisplayFor(x => employee.DepartmentId)</td>  
  42.   
  43.         </tr>  
  44.     }  
  45.   
  46. </table>  
  47.   
  48. <style>  
  49.     table {  
  50.         font-family: arial, sans-serif;  
  51.         border-collapse: collapse;  
  52.         width: 100%;  
  53.     }  
  54.   
  55.     td, th {  
  56.         border: 1px solid #dddddd;  
  57.         text-align: left;  
  58.         padding: 4px;  
  59.     }  
  60. </style>  
In order to execute the above code, we have two different URL's provided in RouteConfig as Convention or like the user defined routing like below.
 
"Employee/GetEmployeeInfo/{employeeId}",
"Employee/GetEmployeeInfoByDept/{departmentId}",
 
When the user requests for "Employee/GetEmployeeInfo/{1001}", then GetEmployeeByEId Action Method of EmployeeController handles the request and returns the Employee details whose EmployeeId is 1001, similarly when user requests for "Employee/GetEmployeeInfoByDept/{1701}", then the GetEmployeeByDId Action Method of EmployeeController handles the request and returns an Employee or a list of Employees whose departmentId is 1701.
 
The output for the above code is shown below.
 
 
 
 

Conclusion

 
With the above RouteConfig, the user can create his own custom routing or convention routing when they don't want to work with default routing. The drawback of convention routing is that if there are multiple requested URL's or large applications, then the user needs to add multiple convention routing in RouteConfig class. This can become complex work. Furthermore, if the user is required to change the Action Method name, then he also need to change the Action Method name in RouteConfig class. In order to overcome this drawback, we will check out Attribute Routing, reviewed in our next post.
 
Thanks for reading my article, hope this helps you.