C#におけるURLエンコードとデコードの違いと注意点
C#ではURLエンコードやデコードを行う方法として、主に以下の2つのAPIが利用されます:
Uri.EscapeDataString
/Uri.UnescapeDataString
HttpUtility.UrlEncode
/HttpUtility.UrlDecode
これらのAPIは似た役割を持ちますが、それぞれ異なる用途や仕様に基づいて設計されています。本記事では、この2つの違いや使用方法、そして注意点について詳しく解説します。
1. Uri.EscapeDataString
/ Uri.UnescapeDataString
の概要
特徴
- URI(Uniform Resource Identifier)全体のエンコード・デコードに使用します。
- RFC 3986標準に基づいて動作します。
-
スペースは
%20
にエンコードされ、デコード時も%20
として扱われます。 -
+
はエンコード対象ではなく、そのまま保持されます。
使用例
string data = "Hello World+Test";
// エンコード
string encoded = Uri.EscapeDataString(data); // "Hello%20World%2BTest"
// デコード
string decoded = Uri.UnescapeDataString(encoded); // "Hello World+Test"
用途
- URI全体またはその一部(パスやクエリ文字列など)を安全にエンコードする場合に使用します。
2. HttpUtility.UrlEncode
/ HttpUtility.UrlDecode
の概要
特徴
- HTTPリクエストやHTMLフォームデータのエンコード・デコードに特化しています。
- HTMLフォームエンコード仕様(W3C基準)に従います。
-
スペースは
+
にエンコードされ、デコード時に+
はスペースに戻ります。
使用例
using System.Web;
string data = "Hello World+Test";
// エンコード
string encoded = HttpUtility.UrlEncode(data); // "Hello+World%2bTest"
// デコード
string decoded = HttpUtility.UrlDecode(encoded); // "Hello World+Test"
用途
- クエリ文字列やHTMLフォームのデータを処理する場合に使用します。
3. 主な違い
特徴 |
Uri.EscapeDataString / Uri.UnescapeDataString
|
HttpUtility.UrlEncode / HttpUtility.UrlDecode
|
---|---|---|
対象仕様 | RFC 3986 (URI標準) | HTMLフォームエンコード (HTTPリクエスト仕様) |
スペースの扱い | %20 |
+ |
+ の扱い |
そのまま保持 | エンコード時は%2B 、デコード時はスペース扱い |
使用場面 | URI全体やその一部のエンコード | クエリ文字列やフォームデータのエンコード |
依存する名前空間 | System |
System.Web |
4. ++
がスペースに変換される問題と対策
HttpUtility.UrlDecode
を使用すると、+
がスペースに変換されることがあります。この仕様により、例えばファイル名に含まれる++
が正しく処理されず、問題が発生するケースがあります。
問題例
using System.Web;
string encodedFilename = "サンプルファイル1%2B%2B.xlsx";
// デコードすると `++` がスペースに
string decodedFilename = HttpUtility.UrlDecode(encodedFilename); // "サンプルファイル1 .xlsx"
対策方法
-
デコード後に手動で
+
を復元するstring decodedFilename = HttpUtility.UrlDecode(encodedFilename); decodedFilename = decodedFilename.Replace(" ", "+");
-
Uri.UnescapeDataString
を使用するstring decodedFilename = Uri.UnescapeDataString(encodedFilename);
-
+
を事前に%2B
にエンコードするstring originalFilename = "サンプルファイル1++.xlsx"; string encodedFilename = Uri.EscapeDataString(originalFilename);
5. どちらを選ぶべきか?
Uri.EscapeDataString
/ Uri.UnescapeDataString
を選ぶ場合
- URIそのものをエンコード/デコードする場合。
- 一般的な文字列(例: ファイル名)をURIに安全に含めたい場合。
HttpUtility.UrlEncode
/ HttpUtility.UrlDecode
を選ぶ場合
- HTTPリクエストやHTMLフォームのデータをエンコード/デコードする場合。
- Webアプリケーションでクエリ文字列を処理する場合。
6. 注意点
-
Uri.EscapeDataString
の文字数制限
非常に長い文字列(約32,766文字以上)をエンコードしようとするとUriFormatException
が発生する可能性があります。 -
HttpUtility
の依存性
HttpUtility
はSystem.Web
名前空間に依存しており、.NET Coreや.NET 5以降のプロジェクトでは利用できない場合があります。この場合はSystem.Net.WebUtility
を検討してください。
まとめ
-
URI全体や一般的なデータを安全にエンコードする場合は、
Uri.EscapeDataString
を使用します。 -
HTTPリクエストやフォームデータを処理する場合は、
HttpUtility.UrlEncode
を使用します。 - 問題の状況に応じて適切なAPIを選択し、特定の文字(例:
+
)に関する仕様の違いに注意してください。
この記事が、C#でURLエンコード/デコードを行う際の参考になれば幸いです!