ASP.NET Core Complete Tutorial (ShopNest)
Lesson 6 of 75 8% of course

Routing in ASP.NET Core — Conventional and Attribute Routing

1 · 6 min · 5/24/2026

Learn Routing in ASP.NET Core — Conventional and Attribute Routing in our free ASP.NET Core Complete Tutorial (ShopNest) series. Step-by-step explanations, examples, and interview tips on Toolliyo Academy.

Sign in to track progress and bookmarks.

Routing in ASP.NET Core — ShopNest Blog
Article 6 of 75 · Module 1: Foundations · ShopNest Blog Website
Target keyword: asp.net core routing · Read time: ~26 min · .NET: 8 / 9 · Project: ShopNest Blog Website

Introduction

Routing is how ASP.NET Core maps an incoming URL like /blog/2025/build-shopnest-with-aspnet-core to the correct controller action. Without routing, every request would hit one endpoint — your blog could never show individual posts, archives, or category pages.

ASP.NET Core supports two complementary styles: conventional routing (central templates in Program.cs) and attribute routing (routes declared on controllers and actions with [Route]). This lesson builds SEO-friendly blog URLs for ShopNest, covers constraints, areas, optional parameters, conflict resolution, and debugging — topics that appear in virtually every MVC interview.

After this article you will

  • Configure conventional route templates with defaults and constraints
  • Apply attribute routing with HTTP verb attributes
  • Use route constraints (int, regex, custom)
  • Set up area routing for admin vs public blog
  • Design SEO-friendly slugs and debug route mismatches

Prerequisites

How routing works — the request pipeline

Level 1 — Analogy

Routing is like a postal sorting office. The envelope (HTTP request) has an address (URL path). The sorter reads the address, looks up rules (route table), and delivers the letter to the right department (controller) and desk (action).

Level 2 — Technical

After middleware runs, UseRouting() selects an endpoint. UseEndpoints() / MapControllerRoute registers MVC routes. The router produces a RouteData dictionary with keys like controller, action, id, plus custom tokens.

// Default conventional route (Program.cs)
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

URL /Posts/Show/42PostsController.Show(42). The ? on {id?} makes the segment optional.

Common misconceptions

❌ MYTH: You must choose conventional OR attribute routing.
✅ TRUTH: Both can coexist; attribute routes often take precedence when matched.

❌ MYTH: Route order never matters.
✅ TRUTH: First matching route wins — register specific routes before catch-all patterns.

Conventional routing — templates, defaults, constraints

Conventional routes are defined once and apply to all controllers following naming conventions.

// ShopNest Blog — SEO-friendly post URLs
app.MapControllerRoute(
    name: "blogPost",
    pattern: "blog/{year:int}/{month:int}/{slug}",
    defaults: new { controller = "Posts", action = "Show" });

app.MapControllerRoute(
    name: "blogArchive",
    pattern: "blog/archive/{year:int}/{month:int?}",
    defaults: new { controller = "Posts", action = "Archive" });

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
TokenMeaningExample
{slug}Captures any stringbuild-shopnest-with-aspnet-core
{year:int}Constraint — digits only2025
{month:int?}Optional constrained segmentOmit for yearly archive
defaultsValues when segment missingcontroller = "Posts"

Attribute routing

Place routes directly on controllers and actions — ideal for REST-style or versioned APIs and when URLs don't follow one global template.

[Route("blog")]
public class PostsController : Controller
{
    [HttpGet("{year:int}/{month:int}/{slug}")]
    public IActionResult Show(int year, int month, string slug) { ... }

    [HttpGet("archive")]
    [HttpGet("archive/{year:int}")]
    public IActionResult Archive(int? year) { ... }

    [HttpPost("create")]
    public IActionResult Create([FromForm] PostCreateViewModel model) { ... }
}

Combine with HTTP verbs: [HttpGet], [HttpPost], [HttpPut], [HttpDelete]. Same path + different verbs = different actions (like REST).

Route constraints

// Built-in constraints
{id:int}           // 123
{slug:minlength(3)} // at least 3 chars
{slug:regex(^[a-z0-9-]+$)}  // lowercase slug only
{page:range(1,9999)}

// Custom constraint (implements IRouteConstraint)
{slug:slug}  // register in Program.cs:
// options.ConstraintMap.Add("slug", typeof(SlugRouteConstraint));

Constraints reject invalid URLs early — /blog/abc/not-a-year/my-post returns 404 instead of hitting your action with bad data.

Area routing

Areas partition large apps — ShopNest Blog Admin vs public site.

// Areas/Admin/Controllers/PostsController.cs
[Area("Admin")]
[Route("admin/blog/[controller]")]
public class PostsController : Controller
{
    [HttpGet("")]
    public IActionResult Index() => View();
}

// Program.cs
app.MapControllerRoute(
    name: "areas",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

Admin posts list: /Admin/Posts or /admin/blog/Posts depending on attribute prefix.

Conflicting routes — resolution

  • Specific before general: Register blog/{year}/{slug} before {controller}/{action}.
  • Ambiguous action: Two actions match same template — add constraints or rename routes.
  • Link generation: Use named routes: asp-route="blogPost" in Tag Helpers.
// Debugging: log matched endpoint (Development)
app.Use(async (ctx, next) =>
{
    await next();
    var ep = ctx.GetEndpoint();
    if (ep != null) Console.WriteLine($"Endpoint: {ep.DisplayName}");
});

Install Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation and enable detailed errors in Development to see which route failed.

Hands-on — ShopNest Blog routing

  1. Add Post model with Slug, PublishedAt.
  2. Register blogPost and blogArchive routes in Program.cs.
  3. Implement PostsController.Show loading by year/month/slug.
  4. Generate slugs on create: title.ToLower().Replace(" ", "-") (or Slugify library).
  5. Test: valid URL, wrong year (404), optional archive month.
public IActionResult Show(int year, int month, string slug)
{
    var post = _db.Posts.FirstOrDefault(p =>
        p.Slug == slug && p.PublishedAt.Year == year && p.PublishedAt.Month == month);
    if (post == null) return NotFound();
    return View(post);
}

Common errors & best practices

  • 404 on valid URL: Route registered after default route — reorder in Program.cs.
  • Optional parameter in middle: Not allowed — put optional segments at the end.
  • SEO: Use readable slugs, lowercase, hyphens; include date in path for blogs if desired.
  • Production: Prefer attribute routing for APIs; conventional for traditional MVC sites.

Interview questions

Q1: Conventional vs attribute routing?
A: Conventional uses central templates; attribute routes decorate controllers/actions — attribute gives fine-grained control per endpoint.

Q2: What does {id?} mean?
A: Optional route parameter — URL works with or without that segment.

Q3: How do route constraints help?
A: They validate segment format before model binding — invalid URLs never reach the action.

Q4: What is an Area?
A: Logical folder for controllers/views (e.g. Admin) with separate route prefix.

Q5: Which middleware enables routing?
A: UseRouting() selects endpoint; UseEndpoints/MapControllers executes it.

Summary

  • Routing maps URLs to controller actions via conventional templates or attributes
  • Use constraints and optional parameters for safe, flexible URLs
  • Areas separate Admin from public ShopNest Blog
  • Register specific routes first; debug with endpoint logging

Previous: Controllers and Actions
Next: Views and Razor Syntax

FAQ

Can I use both conventional and attribute routing in one app?

Yes. Many ShopNest-style apps use conventional routes for MVC pages and attribute routes for API controllers in the same project.

Use Tag Helpers: <a asp-route="blogPost" asp-route-year="2025" asp-route-month="5" asp-route-slug="my-post"> or Url.Action with route values.

Test your knowledge

Quizzes linked to this course—pass to earn certificates.

Browse all quizzes
ASP.NET Core Complete Tutorial (ShopNest)

On this page

Introduction After this article you will Prerequisites How routing works — the request pipeline Level 1 — Analogy Level 2 — Technical Conventional routing — templates, defaults, constraints Attribute routing Route constraints Area routing Conflicting routes — resolution Hands-on — ShopNest Blog routing Common errors &amp; best practices Interview questions Summary FAQ Can I use both conventional and attribute routing in one app? How do I generate links that match my custom blog route?
Module 1: Foundations
What is ASP.NET Core? Complete Guide Setting Up ASP.NET Core Development Environment ASP.NET Core Project Structure Explained MVC Architecture in ASP.NET Core — Complete Guide Controllers and Actions in ASP.NET Core Routing in ASP.NET Core — Conventional and Attribute Routing Views and Razor Syntax in ASP.NET Core Layouts, Partial Views and View Components Models and ViewModels in ASP.NET Core Forms, Model Binding and Validation in ASP.NET Core Tag Helpers in ASP.NET Core — Complete Guide Static Files, Bundling and Minification in ASP.NET Core
Module 2: Entity Framework Core
Entity Framework Core — Introduction and Setup EF Core Code First — Models, Migrations, Database EF Core CRUD Operations — Create, Read, Update, Delete EF Core LINQ Queries — Beginner to Advanced EF Core Relationships — One-to-One, One-to-Many, Many-to-Many EF Core Fluent API — Advanced Configuration EF Core Repository Pattern and Unit of Work EF Core Performance Optimization Database First Approach with EF Core (Scaffold) EF Core with SQL Server — Advanced Features
Module 3: Dependency Injection & Middleware
Dependency Injection in ASP.NET Core — Complete Guide Middleware in ASP.NET Core — Complete Guide Configuration in ASP.NET Core — appsettings, Environment Variables, Secrets Filters in ASP.NET Core — Action, Authorization, Exception, Resource, Result Logging in ASP.NET Core — ILogger, Serilog, NLog Error Handling and Exception Management in ASP.NET Core
Module 4: Authentication & Security
ASP.NET Core Identity — Complete Setup Guide Authentication in ASP.NET Core — Cookie and JWT Authorization in ASP.NET Core — Roles, Policies, Claims JWT Authentication with Refresh Tokens — Complete Implementation OAuth2 and External Login (Google, Facebook, Microsoft) Data Protection and Encryption in ASP.NET Core HTTPS, SSL Certificates and Security Best Practices
Module 5: Web API
Building REST APIs with ASP.NET Core — Complete Guide API Versioning in ASP.NET Core Swagger / OpenAPI Documentation in ASP.NET Core Input Validation in Web APIs — FluentValidation and Data Annotations Pagination, Filtering and Sorting in ASP.NET Core APIs HTTP Client and Consuming External APIs in ASP.NET Core Minimal APIs in ASP.NET Core .NET 8 SignalR — Real-Time Web Applications
Module 6: Advanced Architecture
Clean Architecture in ASP.NET Core CQRS Pattern with MediatR in ASP.NET Core Repository Pattern — Deep Dive with Generic Repository Background Services and Hosted Services in ASP.NET Core Caching in ASP.NET Core — In-Memory, Distributed, Redis Health Checks in ASP.NET Core AutoMapper in ASP.NET Core Microservices with ASP.NET Core — Introduction Message Queues with RabbitMQ / Azure Service Bus in ASP.NET Core gRPC with ASP.NET Core
Module 7: Testing
Unit Testing ASP.NET Core with xUnit and Moq Integration Testing in ASP.NET Core Testing EF Core — In-Memory vs SQLite Performance Testing and Load Testing ASP.NET Core APIs Test-Driven Development (TDD) in ASP.NET Core
Module 8: Deployment & DevOps
Deploying ASP.NET Core to IIS on Windows Server Docker and Containerization for ASP.NET Core Deploying ASP.NET Core to Azure App Service CI/CD with GitHub Actions for ASP.NET Core Azure SQL Database with ASP.NET Core Environment Configuration and Secrets Management
Module 9: Real-World Projects
Build a Complete Blog Website with ASP.NET Core MVC Build an E-Commerce Product Catalog API (ASP.NET Core Web API) Build a Student Management System (Complete CRUD App) Build a Job Portal (Full Stack ASP.NET Core) Build a REST API with Clean Architecture — Complete Guide Build a Real-Time Chat App with SignalR and ASP.NET Core
Module 10: Advanced Topics
Blazor WebAssembly and Blazor Server — Complete Guide gRPC, GraphQL and Alternative API Styles in ASP.NET Core Rate Limiting and API Throttling in ASP.NET Core .NET 8 Output Caching in ASP.NET Core .NET 8 ASP.NET Core .NET 9 New Features — Complete Guide