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!