Section 3 of 6

Route Parameters

🎯 What You'll Learn

  • Required route parameters
  • Optional route parameters
  • Default values
  • Catch-all parameters
  • Complex route patterns
  • Parameter binding

What are Route Parameters?

Route parameters capture values from the URL and pass them to your action methods.

Route Parameter Example Text
Route: /api/products/{id}
URL:   /api/products/123
       ↓
Parameter: id = 123

Required Parameters

Required parameters must be present in the URL.

Required Parameter C#
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
    return Ok($"Product {id}");
}

// ✅ /api/products/123 → id = 123
// ❌ /api/products → 404 Not Found

Multiple Required Parameters

Multiple Parameters C#
[HttpGet("{category}/{id}")]
public IActionResult GetProduct(string category, int id)
{
    return Ok($"Category: {category}, Product: {id}");
}

// /api/products/electronics/123
// → category = "electronics", id = 123

Optional Parameters

Optional parameters use ? suffix and can be omitted.

Optional Parameter C#
[HttpGet("{id?}")]
public IActionResult GetProducts(int? id)
{
    if (id.HasValue)
        return Ok($"Product {id}");
    
    return Ok("All products");
}

// ✅ /api/products → id = null
// ✅ /api/products/123 → id = 123
ℹ️ Nullable Types

Optional route parameters should use nullable types (int?, string?) in the action method.

Default Values

Default values are used when the parameter is not provided.

Default Value C#
[HttpGet("{page=1}")]
public IActionResult GetProducts(int page)
{
    return Ok($"Page {page}");
}

// /api/products → page = 1 (default)
// /api/products/5 → page = 5

Conventional Routing Default

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

// / → Home/Index
// /Products → Products/Index
// /Products/Details/123 → Products/Details/123

Catch-All Parameters

Catch-all parameters capture the rest of the URL path.

Catch-All Parameter C#
[HttpGet("{*path}")]
public IActionResult CatchAll(string path)
{
    return Ok($"Path: {path}");
}

// /api/files/docs/2024/report.pdf
// → path = "docs/2024/report.pdf"

Practical Use Case: File Serving

File Controller C#
[Route("api/files")]
public class FilesController : ControllerBase
{
    [HttpGet("{*filePath}")]
    public IActionResult GetFile(string filePath)
    {
        var fullPath = Path.Combine("uploads", filePath);
        
        if (!System.IO.File.Exists(fullPath))
            return NotFound();
        
        return PhysicalFile(fullPath, "application/octet-stream");
    }
}

Complex Route Patterns

Blog Post Example

Blog Routes C#
[Route("blog")]
public class BlogController : Controller
{
    // /blog/2024/12/10/my-post-title
    [HttpGet("{year}/{month}/{day}/{slug}")]
    public IActionResult Post(
        int year,
        int month,
        int day,
        string slug)
    {
        return Ok($"Post: {year}-{month}-{day} - {slug}");
    }
}

Product Search Example

Search Routes C#
[Route("api/products")]
public class ProductsController : ControllerBase
{
    // /api/products/category/electronics/price/100-500
    [HttpGet("category/{category}/price/{minPrice}-{maxPrice}")]
    public IActionResult SearchByPriceRange(
        string category,
        decimal minPrice,
        decimal maxPrice)
    {
        return Ok($"{category}: ${minPrice}-${maxPrice}");
    }
}

Parameter Binding

ASP.NET Core automatically binds route parameters to action method parameters.

Automatic Type Conversion

Type Conversion C#
[HttpGet("{id}/{active}")]
public IActionResult GetProduct(int id, bool active)
{
    // /api/products/123/true
    // → id = 123 (int), active = true (bool)
    return Ok();
}

Custom Model Binding

Complex Object from Route C#
public record DateRange(int Year, int Month, int Day);

[HttpGet("{year}/{month}/{day}")]
public IActionResult GetByDate([FromRoute] DateRange date)
{
    // /api/products/2024/12/10
    // → date.Year = 2024, date.Month = 12, date.Day = 10
    return Ok(date);
}

Complete InvenTrack Example

Controllers/ProductsController.cs C#
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    // Required parameter
    // GET /api/products/123
    [HttpGet("{id:int}")]
    public IActionResult GetById(int id)
    {
        return Ok($"Product {id}");
    }

    // Optional parameter
    // GET /api/products/page or /api/products/page/2
    [HttpGet("page/{pageNumber?}")]
    public IActionResult GetPage(int? pageNumber)
    {
        var page = pageNumber ?? 1;
        return Ok($"Page {page}");
    }

    // Default value
    // GET /api/products/list or /api/products/list/10
    [HttpGet("list/{pageSize=20}")]
    public IActionResult GetList(int pageSize)
    {
        return Ok($"Page size: {pageSize}");
    }

    // Multiple parameters
    // GET /api/products/category/electronics/123
    [HttpGet("category/{category}/{id}")]
    public IActionResult GetByCategory(string category, int id)
    {
        return Ok($"{category}: Product {id}");
    }

    // Complex pattern
    // GET /api/products/price/100-500
    [HttpGet("price/{minPrice:decimal}-{maxPrice:decimal}")]
    public IActionResult GetByPriceRange(decimal minPrice, decimal maxPrice)
    {
        return Ok($"Price range: ${minPrice} - ${maxPrice}");
    }

    // Catch-all for file paths
    // GET /api/products/images/2024/product-123.jpg
    [HttpGet("images/{*imagePath}")]
    public IActionResult GetImage(string imagePath)
    {
        return Ok($"Image path: {imagePath}");
    }
}

Key Takeaways

  • Required parameters: {id} - must be present
  • Optional parameters: {id?} - can be omitted
  • Default values: {page=1} - fallback value
  • Catch-all: {*path} - captures rest of URL
  • Multiple parameters: {category}/{id}
  • Complex patterns: {min}-{max}
  • Automatic binding: Route values → action parameters
  • Type conversion: Strings → int, bool, decimal, etc.
  • Nullable types: Use for optional parameters
🎯 Next Steps

You now understand route parameters! In the next section, we'll explore Route Constraints—how to restrict parameter values and ensure only valid URLs match your routes.