Skip to main content

A custom slugify parameter transformer in route pattern blog\{article:slugify} with Url.Action(new { article = "MyTestArticle" }) generates blog\my-test-article.

//
// Infrastructure/SlugifyParameterTransformer.cs

using System.Text.RegularExpressions;

namespace Infrastructure;

/// <remarks>
/// For example, a custom slugify parameter transformer in route pattern blog\{article:slugify} with Url.Action(new { article = "MyTestArticle" }) generates blog\my-test-article.
/// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-6.0#parameter-transformers
/// </remarks>
public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string? TransformOutbound(object? value)
    {
        if (value is null)
        {
            return null;
        }

        return Regex.Replace(
                value.ToString()!,
                "([a-z])([A-Z])",
                "$1-$2",
                RegexOptions.CultureInvariant,
                TimeSpan.FromMilliseconds(100))
            .ToLowerInvariant();
    }
}

//
// Then, configure the service at startup in your Program.cs:
using Infrastructure;

// ----------------------------------------
// Add services to the container
// ----------------------------------------

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    // Slugify and lowercase all route params
    options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
});

// ----------------------------------------
// Configure the HTTP request pipeline
// ----------------------------------------

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapControllers();

app.Run();