C# Tips | 文字列処理:URLエンコード

C# C#
スポンサーリンク

はじめに 「URLエンコード」は“文字列をURLの世界に適応させる変換”

URLエンコードは、
「URLの中でそのまま使うと問題が出る文字を、安全な形に変換する」処理です。

日本語、スペース、記号類などをそのままURLに入れると、
ブラウザやサーバー側で正しく解釈されなかったり、途中で切れたりします。
そこで、そういった文字を「%xx 形式」の安全な文字列に変換してからURLに載せる——
これがURLエンコードです。

C#では、System.Net.WebUtilitySystem.Web.HttpUtility を使うのが基本ですが、
「どのメソッドを使うか」「何をエンコードするか」を理解しておかないと、
意図しない二重エンコードやバグにつながります。

ここから、初心者向けに、
URLエンコードの考え方、C#での基本メソッド、
クエリパラメータでの具体例、実務ユーティリティとしてのまとめ方まで、
順番にかみ砕いて説明していきます。


URLエンコードの基本概念

なぜURLエンコードが必要なのか

URLには「そのまま使ってよい文字」と「特別な意味を持つ文字」があります。
例えば、?& は「クエリパラメータの区切り」として使われますし、
= は「キーと値の区切り」に使われます。

また、日本語やスペース、#% などは、
そのままURLに入れると正しく解釈されなかったり、
途中で切れてしまう原因になります。

そこで、
「URLの中で特別な意味を持つ文字」
「ASCII以外の文字(日本語など)」
を、%E3%81%93 のような「%+16進数」の形に変換して、
URLとして安全に扱えるようにする——
これがURLエンコードの役割です。

どの部分をエンコードするのか

URL全体を丸ごとエンコードするのではなく、
通常は「クエリパラメータの値」や「パスの一部」など、
“変動する部分”だけをエンコードします。

例えば、次のようなURLを考えます。

https://example.com/search?q=こんにちは&lang=ja

ここでURLエンコードするのは、こんにちは の部分です。
q=&lang=ja までエンコードしてしまうと、
サーバー側でクエリパラメータとして認識されなくなってしまいます。


C#での基本:WebUtility.UrlEncode を使う

最もシンプルなURLエンコード

.NET(.NET Core / .NET 5+)で、
URLエンコードにまず使ってよいのは System.Net.WebUtility.UrlEncode です。

using System.Net;

public static class UrlEncodeUtil
{
    public static string Encode(string? value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return string.Empty;
        }

        return WebUtility.UrlEncode(value);
    }
}
C#

このメソッドは、
内部的にUTF-8でエンコードし、
必要な文字を %xx 形式に変換してくれます。

動作例でイメージをつかむ

Console.WriteLine(UrlEncodeUtil.Encode("こんにちは"));
// 例: %E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF

Console.WriteLine(UrlEncodeUtil.Encode("A B&C?"));
// 例: A+B%26C%3f
C#

ここで注目したいのは、
スペースが + に変換されていることです。

URLエンコードでは、
スペースを %20 ではなく + にするスタイルがよく使われます。
%20 を使うパターンもありますが、UrlEncode+ を採用します)


HttpUtility.UrlEncode との違いと選び方

System.Web.HttpUtility.UrlEncode は主に古いASP.NET向け

フルフレームワーク(.NET Framework)や古いASP.NETでは、
System.Web.HttpUtility.UrlEncode がよく使われていました。

using System.Web;

string encoded = HttpUtility.UrlEncode("こんにちは");
C#

しかし、System.Web は .NET Core / .NET 5+ では基本的に使いません。
新しめの環境では、System.Net.WebUtility.UrlEncode を使うのが素直です。

もしレガシーなASP.NETアプリを触っていて HttpUtility が出てきたら、
「同じようなことをしているが、今から新規で使うなら WebUtility を選ぶ」
くらいの理解でOKです。


実務でよくある使い方:クエリパラメータの組み立て

文字列連結でやるときの基本形

例えば、検索画面から「キーワード」を受け取って、
外部サイトの検索URLを組み立てるとします。

string keyword = "C# 入門";
string encodedKeyword = UrlEncodeUtil.Encode(keyword);

string url = "https://example.com/search?q=" + encodedKeyword;

Console.WriteLine(url);
// https://example.com/search?q=C%23+%E5%85%A5%E9%96%80
C#

ここでのポイントは、
q= の右側だけをエンコードしていることです。

"https://example.com/search?q=" までエンコードしてしまうと、
:/? まで %xx になってしまい、
URLとして機能しなくなります。

複数パラメータを扱う場合

パラメータが増えても考え方は同じです。

string keyword = "C# 入門";
string lang = "ja-JP";

string q = UrlEncodeUtil.Encode(keyword);
string l = UrlEncodeUtil.Encode(lang);

string url = $"https://example.com/search?q={q}&lang={l}";
C#

&= はURLの構造を表す記号なのでエンコードせず、
値の部分だけをエンコードします。


ここが重要:二重エンコードに注意する

「すでにエンコード済みのもの」をもう一度エンコードしない

よくあるバグの一つが、「二重エンコード」です。

例えば、すでにBase64やURLエンコードされた文字列に対して、
さらに UrlEncode をかけてしまうと、
サーバー側で正しくデコードできなくなります。

string once = UrlEncodeUtil.Encode("こんにちは");
string twice = UrlEncodeUtil.Encode(once);

Console.WriteLine(once);
// %E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF

Console.WriteLine(twice);
// %25E3%2581%2593%25E3%2582%2593%25E3%2581%25AB...
C#

% 自体が %25 にエンコードされてしまい、
元に戻すには2回デコードしないといけない状態になります。

実務では、

「どのタイミングでエンコードするか」
「どの層までエンコード済みの値を渡すか」

をチーム内で決めておくことがとても大事です。


パスの一部をエンコードしたい場合

クエリではなく、パスセグメントとして使うケース

例えば、次のようなURLを考えます。

https://example.com/users/山田太郎

この 山田太郎 の部分をURLに安全に載せたい場合、
パスセグメントとしてエンコードする必要があります。

WebUtility.UrlEncode でもある程度対応できますが、
パス用には Uri.EscapeDataString を使うことも多いです。

string name = "山田太郎";
string encodedName = Uri.EscapeDataString(name);

string url = $"https://example.com/users/{encodedName}";
C#

Uri.EscapeDataString は、
「URIの一部として使う文字列」をエスケープするメソッドで、
スペースを %20 にするなど、UrlEncode と少し挙動が違います。

クエリパラメータの値 → WebUtility.UrlEncode
パスセグメント → Uri.EscapeDataString

という使い分けを覚えておくと、実務で迷いにくくなります。


業務ユーティリティとしてのまとめ方

用途ごとにメソッドを分ける

実務で使いやすくするには、
「何をエンコードするのか」をメソッド名で明確にしておくとよいです。

例えば、次のようなユーティリティクラスを用意できます。

using System;
using System.Net;
using System.Text;

public static class UrlEncoding
{
    // クエリパラメータの値用(UTF-8)
    public static string EncodeQueryValue(string? value)
    {
        if (string.IsNullOrEmpty(value))
        {
            return string.Empty;
        }

        return WebUtility.UrlEncode(value);
    }

    // パスセグメント用(UTF-8)
    public static string EncodePathSegment(string? segment)
    {
        if (string.IsNullOrEmpty(segment))
        {
            return string.Empty;
        }

        return Uri.EscapeDataString(segment);
    }
}
C#

呼び出し側は、

クエリの値 → EncodeQueryValue
パスの一部 → EncodePathSegment

というように、意図に応じて使い分けられます。

nullや空文字の扱いをユーティリティ側で決めておく

どちらのメソッドも、
null や空文字なら空文字を返すようにしています。

これにより、呼び出し側で毎回

if (value != null) { ... }
C#

といったガードを書く必要がなくなり、
業務コードがすっきりします。


まとめ 「URLエンコードユーティリティ」は“文字列をURLのルールに合わせて安全に流すための変換器”

URLエンコードは、
「文字列をURLの世界に適応させるための変換」です。

C#で押さえておきたいポイントは、

WebUtility.UrlEncode を使えば、UTF-8前提でクエリ値を安全にエンコードできること。
URL全体ではなく、「値の部分だけ」をエンコードすること。
二重エンコードを避けるために、「どこでエンコードするか」を設計として決めておくこと。
パスセグメントには Uri.EscapeDataString を使うなど、用途ごとにメソッドを分けると実務で扱いやすいこと。

ここまで理解できれば、「なんとなくUrlEncodeしている」段階から一歩進んで、
“URLの構造と用途を意識した、業務で使えるURLエンコードユーティリティ”を、
自分のC#コードの中に自然に組み込めるようになっていきます。

タイトルとURLをコピーしました