C#におけるURLエンコードとデコードの違いと注意点
C#ではURLエンコードやデコードを行う方法として、主に以下の2つのAPIが利用されます:
Uri.EscapeDataString/Uri.UnescapeDataStringHttpUtility.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エンコード/デコードを行う際の参考になれば幸いです!