URL Pattern Matching in .NET

 
 
  • Gérald Barré

Working with URLs in .NET applications often involves pattern matching for routing, security policies, or content filtering. While you could write custom regex patterns or string comparisons, there's a better way: the Meziantou.Framework.Uri package brings standardized URL pattern matching to .NET.

This package implements the WHATWG URL Pattern API specification, providing a consistent and powerful way to match URLs against patterns with parameters, wildcards, and modifiers.

#Installation

Install the package via NuGet:

Shell
dotnet add package Meziantou.Framework.Uri

#Basic URL Pattern Matching

The package centers on the UrlPattern class, which lets you define patterns and test URLs against them:

C#
var pattern = UrlPattern.Create(new UrlPatternInit
{
    Protocol = "https",
    Hostname = "example.com",
    Pathname = "/books/:id",
});

bool matches = pattern.IsMatch("https://example.com/books/123"); // true

You can also create patterns from a pattern string:

C#
var pattern = UrlPattern.Create("https://example.com/api/:version/*");

#Features

##Wildcards

Use wildcards to match any path or sequence of segments:

C#
var wildcardPattern = UrlPattern.Create(new UrlPatternInit
{
    Pathname = "/files/*",
});

wildcardPattern.IsMatch("https://example.com/files/a/b/c"); // true

##Optional Parameters

Use modifiers to make parts of the pattern optional:

C#
var optionalPattern = UrlPattern.Create(new UrlPatternInit
{
    Pathname = "/items{/:category}?",
});

optionalPattern.IsMatch("https://example.com/items");       // true
optionalPattern.IsMatch("https://example.com/items/books"); // true

##Case-Insensitive Matching

Enable case-insensitive matching with options:

C#
var caseInsensitivePattern = UrlPattern.Create(
    new UrlPatternInit { Pathname = "/Books/:id" },
    new UrlPatternOptions { IgnoreCase = true });

caseInsensitivePattern.IsMatch("https://example.com/BOOKS/123"); // true

##Pattern Collections

Match against multiple patterns and find the first match:

C#
var collection = new UrlPatternCollection
{
    UrlPattern.Create(new UrlPatternInit { Pathname = "/api/*" }),
    UrlPattern.Create(new UrlPatternInit { Pathname = "/docs/*" }),
};

// Test if any pattern matches
bool anyMatch = collection.IsMatch("https://example.com/api/users"); // true

// Get the first matching pattern
UrlPattern? match = collection.FindPattern("https://example.com/docs/guide");

// Match and extract groups
var result = collection.Match("https://example.com/api/v2/users");

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?