目次
概要
日本語やスペース、特殊記号を含む文字列を URL のパラメータ(クエリ文字列)として安全に使用するために、パーセントエンコーディング(URLエンコード)を行う方法です。 .NET には複数のエンコードメソッドが存在しますが、現代の標準的な用途(RFC 3986準拠)で推奨される Uri.EscapeDataString と、デコード用の WebUtility.UrlDecode を紹介します。
仕様(入出力)
- 入力: URLパラメータに含めたい任意の文字列(日本語、記号、スペース等)。
- 出力: パーセント記号(%)を使用したエンコード済み文字列、およびそれを復元した文字列。
- 前提: .NET 標準ライブラリのみ使用。
基本の使い方
URLのパラメータ値(?key=value の value 部分)を変換する場合は、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.UnescapeDataStringとWebUtility.UrlDecodeは挙動が似ていますが、+をスペースに戻す必要がある場合(フォーム送信データの受け取り等)はWebUtility.UrlDecodeが適しています。
注意点
- スペースの扱い:
Uri.EscapeDataStringはスペースを%20に変換しますが、WebUtility.UrlEncodeは+に変換します。REST API等のモダンなWeb通信では%20が一般的です。 - 文字数制限:
Uri.EscapeDataStringは極端に長い文字列(約32,766文字以上)を渡すと例外 (UriFormatException) を投げることがありましたが、最近の.NETバージョンでは緩和されています。それでも巨大なデータを扱う際は注意が必要です。 - 部分エンコード:
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 を使用するのが最も確実です。
古い HttpUtility や WebUtility は、スペースを + に変換するフォーム形式(MIME type application/x-www-form-urlencoded)が必要な場合にのみ使用してください。
