【C#】URLで使用できない文字をエンコード(エスケープ)する方法

目次

概要

日本語やスペース、特殊記号を含む文字列を URL のパラメータ(クエリ文字列)として安全に使用するために、パーセントエンコーディング(URLエンコード)を行う方法です。 .NET には複数のエンコードメソッドが存在しますが、現代の標準的な用途(RFC 3986準拠)で推奨される Uri.EscapeDataString と、デコード用の WebUtility.UrlDecode を紹介します。

仕様(入出力)

  • 入力: URLパラメータに含めたい任意の文字列(日本語、記号、スペース等)。
  • 出力: パーセント記号(%)を使用したエンコード済み文字列、およびそれを復元した文字列。
  • 前提: .NET 標準ライブラリのみ使用。

基本の使い方

URLのパラメータ値(?key=valuevalue 部分)を変換する場合は、Uri.EscapeDataString を使用するのが最も安全で確実です。

string raw = "C# & .NET";

// エンコード: C%23%20%26%20.NET
// (スペースは %20 に、& は %26 に変換されます)
string encoded = Uri.EscapeDataString(raw);

// デコード: C# & .NET
string decoded = Uri.UnescapeDataString(encoded);

コード全文

ここでは、検索キーワードをURLパラメータとして埋め込むシーンを想定したコードを提示します。

using System;
using System.Net; // WebUtility用

class Program
{
    static void Main()
    {
        // 1. URLパラメータにしたい文字列
        // スペース、日本語、記号(+)が含まれている
        string searchQuery = "ASP.NET Core + C#で開発する";

        Console.WriteLine("--- 1. 元の文字列 ---");
        Console.WriteLine(searchQuery);

        // 2. URLエンコード(推奨: Uri.EscapeDataString)
        // スペースを "%20" に、"+" を "%2B" に変換するなど、RFC 3986 に準拠した厳密な変換を行います。
        string encodedUri = Uri.EscapeDataString(searchQuery);

        Console.WriteLine("\n--- 2. Uri.EscapeDataString (推奨) ---");
        Console.WriteLine(encodedUri);
        // 出力: ASP.NET%20Core%20%2B%20C%23%E3%81%A7%E9%96%8B%E7%99%BA%E3%81%99%E3%82%8B

        // 参考: WebUtility.UrlEncode の場合
        // スペースを "+" に変換するなど、application/x-www-form-urlencoded (HTMLフォーム) 形式になります。
        string encodedWeb = WebUtility.UrlEncode(searchQuery);
        Console.WriteLine("\n--- (参考) WebUtility.UrlEncode ---");
        Console.WriteLine(encodedWeb);
        // 出力: ASP.NET+Core+%2b+C%23%e3%81%a7%e9%96%8b%e7%99%ba%e3%81%99%e3%82%8b

        // 3. URLデコード
        // WebUtility.UrlDecode は "%20" も "+" も両方正しくスペースに戻せます。
        string decoded = WebUtility.UrlDecode(encodedUri);

        Console.WriteLine("\n--- 3. デコード結果 ---");
        Console.WriteLine(decoded);

        if (searchQuery == decoded)
        {
            Console.WriteLine("\n判定: 正常に復元されました。");
        }
    }
}

カスタムポイント

  • パス全体のエンコード: クエリパラメータ単体ではなく、/api/users/user name のようなパス部分をエンコードしたい場合は Uri.EscapeUriString がありましたが、現在は非推奨です。パス構造を維持しつつエンコードするのは複雑なため、パラメータごとに EscapeDataString を適用して組み立てるのが原則です。
  • デコードの使い分け: Uri.UnescapeDataStringWebUtility.UrlDecode は挙動が似ていますが、+ をスペースに戻す必要がある場合(フォーム送信データの受け取り等)は WebUtility.UrlDecode が適しています。

注意点

  1. スペースの扱い: Uri.EscapeDataString はスペースを %20 に変換しますが、WebUtility.UrlEncode+ に変換します。REST API等のモダンなWeb通信では %20 が一般的です。
  2. 文字数制限: Uri.EscapeDataString は極端に長い文字列(約32,766文字以上)を渡すと例外 (UriFormatException) を投げることがありましたが、最近の.NETバージョンでは緩和されています。それでも巨大なデータを扱う際は注意が必要です。
  3. 部分エンコード: http://example.com/?q=あ というURL全体を EscapeDataString に渡してはいけません。http%3A%2F%2F... とプロトコル部分まで変換されてしまい、URLとして機能しなくなります。必ず「パラメータの値」の部分だけを渡してください。

応用

辞書からクエリ文字列を作成する

複数のパラメータをまとめて安全なクエリ文字列(key1=val1&key2=val2...)に変換するヘルパーメソッドの例です。

using System.Collections.Generic;
using System.Linq;

string BuildQueryString(Dictionary<string, string> parameters)
{
    // 各キーと値をエンコードしてから = で繋ぎ、& で結合する
    var terms = parameters.Select(p => 
        $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}");
        
    return "?" + string.Join("&", terms);
}

まとめ

URL全体ではなく、構成要素(値)ごとにエンコードを行ってから組み立てるのが鉄則です。

URLのパラメータ値を作る際は、RFC 3986準拠の Uri.EscapeDataString を使用するのが最も確実です。

古い HttpUtilityWebUtility は、スペースを + に変換するフォーム形式(MIME type application/x-www-form-urlencoded)が必要な場合にのみ使用してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次