ASP.NET Core のキャッチオールルートパラメーターでハマった

例えば、はてなブログのカスタム URL みたいな、entry/ 以下にすべてマッチするルートを定義する場合、ASP.NET Core MVC だと下記のように書く。

[HttpGet("entry/{*path}")]
public async Task<IActionResult> Details(string path)
{
    // IIS Express は %2F を / に戻してくれるが、
    // Kestrel は戻してくれないので、自分で戻す必要がある。
    path = Uri.UnescapeDataString(path);

    // path を使って何かする
}

path ルートパラメーターの値が %2F を含んでいるとき、デバッグ実行だと %2F/ に変換してくれるのに、ビルドしたものを dotnet コマンドで起動すると変換してくれなくて嵌った。どうも、Kestrel はやってくれないみたいだ。一方、IIS Express はやってくれる。デバッグ実行では IIS Express で動かしていて、dotnet コマンドでは Kestrel で動かしていたため遭遇した問題でしたとさ。