To understand the purpose and usage of Route Prefix, let's go through an example by updating the StudentController class as shown below.
namespace AttributeRoutingDemoInMVC.Controllers
{
public class StudentsController : Controller
{
static List<student> students = new List<student>()
{
new Student() { Id = 1, Name = "Shaista" },
new Student() { Id = 2, Name = "Noorain" },
new Student() { Id = 3, Name = "Anam" },
new Student() { Id = 4, Name = "Arshiya" }
};
[HttpGet]
[Route("students")]
public ActionResult GetAllStudents()
{
return View(students);
}
[HttpGet]
[Route("students/{studentID}")]
public ActionResult GetStudentByID(int studentID)
{
Student studentDetails = students.FirstOrDefault(s => s.Id == studentID);
return View(studentDetails);
}
[HttpGet]
[Route("students/{studentID}/courses")]
public ActionResult GetStudentCourses(int studentID)
{
List<string< CourseList = new List<string>();
if (studentID == 1)
CourseList = new List<string>() { "ASP.NET", "C#.NET", "SQL Server" };
else if (studentID == 2)
CourseList = new List<string>() { "ASP.NET MVC", "C#.NET", "ADO.NET" };
else if (studentID == 3)
CourseList = new List<string>() { "ASP.NET WEB API", "C#.NET", "Entity Framework" };
else
CourseList = new List<string>() { "Bootstrap", "jQuery", "AngularJs" };
ViewBag.CourseList = CourseList;
return View();
}
}
}
In the given code, route attributes are applied at the action level to define specific routes. Additionally, if you observe closely, all routes in the StudentsController share a common prefix: "students". This indicates that "students" serves as a consistent starting point for all routes within the StudentsController.
Instead of repeating the common prefix "students" in every action method, we can define it once for the entire StudentController by using the [RoutePrefix] attribute at the controller level. This applies the prefix to all action methods within the controller, as demonstrated below.
namespace AttributeRoutingDemoInMVC.Controllers
{
[RoutePrefix("students")]
public class StudentsController : Controller
{
static List<student> students = new List<student>()
{
new Student() { Id = 1, Name = "Shaista" },
new Student() { Id = 2, Name = "Noorain" },
new Student() { Id = 3, Name = "Anam" },
new Student() { Id = 4, Name = "Arshiya" }
};
[HttpGet]
[Route]
//This will be translated to /students
public ActionResult GetAllStudents()
{
return View(students);
}
[HttpGet]
[Route("{studentID}")]
//This will be translated to /students/2
public ActionResult GetStudentByID(int studentID)
{
Student studentDetails = students.FirstOrDefault(s => s.Id == studentID);
return View(studentDetails);
}
[HttpGet]
[Route("{studentID}/courses")]
//This will be translated to /students/2/course
public ActionResult GetStudentCourses(int studentID)
{
List<string> CourseList = new List<string>();
if (studentID == 1)
CourseList = new List<string>() { "ASP.NET", "C#.NET", "SQL Server" };
else if (studentID == 2)
CourseList = new List<string>() { "ASP.NET MVC", "C#.NET", "ADO.NET" };
else if (studentID == 3)
CourseList = new List<string>() { "ASP.NET WEB API", "C#.NET", "Entity Framework" };
else
CourseList = new List<string>() { "Bootstrap", "jQuery", "AngularJs" };
ViewBag.CourseList = CourseList;
return View();
}
}
}
Let's understand this concept with an example. Begin by creating a new class file named "Teacher.cs" inside the Models folder. To do this, right-click on the Models folder, select Add > Class, name it "Teacher.cs", and then insert the following code into the file.
namespace AttributeRoutingDemoInMVC.Models
{
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Next, include the GetTeachers() action method inside the StudentsController.
public ActionResult GetTeachers()
{
List<teacher> teachers = new List<teacher>()
{
new Teacher() { Id = 1, Name = "Amrin" },
new Teacher() { Id = 2, Name = "Daniya" },
new Teacher() { Id = 3, Name = "Uroosa" }
};
return View(teachers);
}
Once the GetTeachers() action method is added, the StudentsController class will appear as shown below.
namespace AttributeRoutingDemoInMVC.Controllers
{
[RoutePrefix("students")]
public class StudentsController : Controller
{
static List<student> students = new List<student>()
{
new Student() { Id = 1, Name = "Shaista" },
new Student() { Id = 2, Name = "Noorain" },
new Student() { Id = 3, Name = "Anam" },
new Student() { Id = 4, Name = "Arshiya" }
};
[HttpGet]
[Route]
//This will be translated to /students
public ActionResult GetAllStudents()
{
return View(students);
}
[HttpGet]
[Route("{studentID}")]
//This will be translated to /students/2
public ActionResult GetStudentByID(int studentID)
{
Student studentDetails = students.FirstOrDefault(s => s.Id == studentID);
return View(studentDetails);
}
[HttpGet]
[Route("{studentID}/courses")]
//This will be translated to /students/2/course
public ActionResult GetStudentCourses(int studentID)
{
List<string> CourseList = new List<string>();
if (studentID == 1)
CourseList = new List<string>() { "ASP.NET", "C#.NET", "SQL Server" };
else if (studentID == 2)
CourseList = new List<string>() { "ASP.NET MVC", "C#.NET", "ADO.NET" };
else if (studentID == 3)
CourseList = new List<string>() { "ASP.NET WEB API", "C#.NET", "Entity Framework" };
else
CourseList = new List<string>() { "Bootstrap", "jQuery", "AngularJs" };
ViewBag.CourseList = CourseList;
return View();
}
public ActionResult GetTeachers()
{
List<teacher> teachers = new List<teacher>()
{
new Teacher() { Id = 1, Name = "Amrin" },
new Teacher() { Id = 2, Name = "Daniya" },
new Teacher() { Id = 3, Name = "Uroosa" }
};
return View(teachers);
}
}
}
Now, create a GetTeachers.cshtml view and insert the following code into it.
@model IEnumerable<attributeroutingdemoinmvc.models.teacher>
@{
ViewBag.Title = "GetTeachers";
}
<h2>GetTeachers</h2>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Id)
</th>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
</tr>
}
</table>
Our goal is to map the GetTeachers() method to the URI "/tech/teachers".
[Route("tech/teachers")]
public ActionResult GetTeachers()
{
List<teacher> teachers = new List<teacher>()
{
new Teacher() { Id = 1, Name = "Amrin" },
new Teacher() { Id = 2, Name = "Daniya" },
new Teacher() { Id = 3, Name = "Uroosa" }
};
return View(teachers);
}
If we apply the [Route] attribute to the GetTeachers() method as shown in the code above and try to access the tech/teachers URL, we will encounter the error.
However, if we access /students/tech/teachers, the expected output—the list of teachers—will be displayed. This happens because of the [RoutePrefix("students")] attribute applied to StudentsController. Therefore, to ensure that the route works as intended, we need to override the RoutePrefix attribute.
[Route("~/tech/teachers")]
public ActionResult GetTeachers()
{
List<teacher> teachers = new List<teacher>()
{
new Teacher() { Id = 1, Name = "Amrin" },
new Teacher() { Id = 2, Name = "Daniya" },
new Teacher() { Id = 3, Name = "Uroosa" }
};
return View(teachers);
}
With this modification, the GetTeachers() action method is now correctly mapped to the URI "/tech/teachers" as intended.