ASP.NET MVC Routing Overview
In ASP.NET MVC, routing is the process that determines how URLs map to controller actions. This system allows you to create SEO-friendly and readable URLs while also controlling how URL paths map to controllers and their corresponding actions.
ASP.NET MVC uses the Routing Module (part of ASP.NET Core or ASP.NET Framework) to define how URL requests are handled. At the core of this process is the RouteTable
and its collection of routes. These routes are processed by the MVC framework to direct the incoming request to the appropriate controller action.
Core Components of Routing
- RouteTable: A static class that holds the collection of all defined routes.
- RouteConfig: A configuration file (
RouteConfig.cs
) where routes are registered. - Route: Defines a pattern and maps URL paths to controller actions.
- Controller: Handles user interaction and responses based on the routing mechanism.
- Action: Methods within the controller that execute specific logic based on the route.
Defining Routes in ASP.NET MVC
Routes are typically defined in the RouteConfig.cs
file (located in the App_Start
folder). This file has a RegisterRoutes
method where routes are registered in the RouteCollection
object.
Example of a default route in ASP.NET MVC:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
}
}
- Name: A string to name the route (e.g., "Default").
- URL: Defines the URL pattern. For instance,
{controller}/{action}/{id}
matches URLs like/Home/Index/1
. - Defaults: Specifies default values for the route if certain URL parameters are missing. In this example, the default controller is
Home
, and the default action isIndex
. - Constraints: You can also add constraints to a route to ensure that a parameter must meet certain conditions (e.g., be numeric).
Route Parameters
Route parameters in the URL correspond to segments that are parsed and passed to the controller.
- Controller: The first URL segment.
- Action: The second URL segment.
- ID: Optional or required parameters following the action.
Example URL that fits the default route:
This URL maps to the HomeController
's Index
action, passing 5
as the ID parameter.
Custom Routes
In addition to the default route, you can define custom routes to suit more specific URL patterns. For example:
routes.MapRoute
(
name: "ProductRoute",
url: "products/{category}/{id}",
defaults: new { controller = "Products", action = "Category", id = UrlParameter.Optional }
);
This would match URLs like /products/electronics/15
, mapping to the ProductsController
and the Category
action with an ID of 15
.
Attribute Routing
Starting with ASP.NET MVC 5, you can define routes directly at the controller or action level using attributes. This allows for more control and flexibility.
Example of attribute routing:
[Route("products/{category}/{id?}")]
public ActionResult Category(string category, int? id)
{
// Code for handling the category and id
}
To enable attribute routing, add this line to the RouteConfig.cs
file:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Enable attribute routing
routes.MapMvcAttributeRoutes();
routes.MapRoute
(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Route Constraints
Constraints can be applied to limit the parameters to specific values or patterns. For example:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { id = @"\d+" }
// Only allow numeric values for 'id'
);
Here, the constraint ensures that only numeric values can be used for the id
parameter.
Route Precedence
The order in which routes are added to the RouteCollection
matters. Routes are processed in the order they are defined. If two routes match the same URL, the first one registered will be used.
For instance:
routes.MapRoute
(
name: "ProductRoute",
url: "products/{category}/{id}",
defaults: new { controller = "Products", action = "Category", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
In this case, the "ProductRoute"
would be checked before the "Default"
route.
Ignoring Routes
Sometimes you want to ignore specific routes (e.g., static files like images, CSS, etc.). You can achieve this with IgnoreRoute
:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
This ignores requests to files like WebResource.axd
or ScriptResource.axd
.
Complete Implementation Example
Step 1: Setting Up the MVC Application
In an ASP.NET MVC application, routing is configured inside the RouteConfig.cs
file located in the App_Start
folder. When the application starts, the routes are registered in the Global.asax.cs
file.
-
Global.asax.cs
This file is the entry point for the application, and it calls the
RegisterRoutes
method fromRouteConfig.cs
.csharp
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
} -
RouteConfig.cs
This is where we define the routes for the application.
Step 2: Defining Default and Custom Routes in RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
// Ignore route to prevent unnecessary routing to certain resources (like static files)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Default route (controller/action/id)
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// Custom route - handling product details with constraints
routes.MapRoute(
name: "ProductDetails",
url: "products/{category}/{id}",
defaults: new { controller = "Products", action = "Category", id = UrlParameter.Optional },
constraints: new { id = @"\d+" }
// 'id' must be numeric );
// Custom route for blog (e.g. /blog/2023/10/01)
routes.MapRoute(
name: "BlogRoute",
url: "blog/{year}/{month}/{day}",
defaults: new { controller = "Blog", action = "Details", day = UrlParameter.Optional },
constraints: new { year = @"\d{4}", month = @"\d{2}", day = @"\d{2}?" }
);
}
}
- Default Route: Matches URLs like
/Home/Index/5
. - ProductDetails Route: Custom route for a product with category and numeric
id
like/products/electronics/15
. - BlogRoute: Custom route for blog posts by date like
/blog/2023/10/01
.
Step 3: Setting Up Controllers
-
HomeController: Basic controller for the default route.
csharp
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
} -
ProductsController: Controller for handling products.
csharp
public class ProductsController : Controller
{
// Action for the ProductDetails route
public ActionResult Category(string category, int? id)
{
ViewBag.Category = category;
ViewBag.Id = id; return View();
}
} -
BlogController: Controller for handling blog posts by date.
csharp
public class BlogController : Controller
{
public ActionResult Details(int year, int month, int? day)
{
ViewBag.Year = year;
ViewBag.Month = month;
ViewBag.Day = day;
return View();
}
}
Step 4: Enabling Attribute Routing (Optional)
Attribute routing allows us to define routes directly at the controller or action level using attributes. To enable it, add the following in RouteConfig.cs
:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Enable attribute routing
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Now, we can add custom route attributes directly in the controller:
-
ProductsController with Attribute Routing:
csharp
public class ProductsController : Controller
{
[Route("products/{category}/{id:int?}")]
public ActionResult Category(string category, int? id)
{
ViewBag.Category = category;
ViewBag.Id = id;
return View();
}
} -
BlogController with Attribute Routing:
csharp
public class BlogController : Controller
{
[Route("blog/{year:int}/{month:int}/{day:int?}")]
public ActionResult Details(int year, int month, int? day)
{
ViewBag.Year = year;
ViewBag.Month = month;
ViewBag.Day = day;
return View();
}
}
Step 5: Views for Displaying Data
-
Category View (for Products):
Create a view file
Category.cshtml
under theViews/Products
folder.html<h2>Category: @ViewBag.Category</h2> <p>Product ID: @ViewBag.Id</p>
-
Details View (for Blog):
Create a view file
Details.cshtml
under theViews/Blog
folder.html<h2>Blog Details</h2> <p>Date: @ViewBag.Year-@ViewBag.Month-@ViewBag.Day</p>
Step 6: Testing Routes
- Default Route: Navigating to
/
or/Home/Index
should route to theHomeController
'sIndex
action. - Product Route: Navigating to
/products/electronics/15
should invoke theCategory
action inProductsController
, displaying the category "electronics" and ID15
. - Blog Route: Navigating to
/blog/2023/10/01
should invoke theDetails
action inBlogController
, displaying the date.
Conclusion
Routing is a powerful and flexible mechanism in ASP.NET MVC that allows you to define how URLs are mapped to controllers and actions. With features like route constraints, custom routes, and attribute routing, you have fine control over how users navigate your application.
If you're building a RESTful API or just structuring your app for SEO and user-friendly URLs, ASP.NET MVC's routing system provides the tools to get it right.