web-dev-qa-db-ja.com

Server.UrlEncodeとHttpUtility.UrlEncode

Server.UrlEncodeとHttpUtility.UrlEncodeに違いはありますか?

171
Manu

HttpServerUtility.UrlEncodeHttpUtility.UrlEncodeを内部的に使用します。特に違いはありません。 Server.UrlEncodeが存在する理由は、従来のASPとの互換性です。

131
Mehrdad Afshari

以前、これらのメソッドで大きな頭痛の種がありました。avoidUrlEncodeの任意のバリアントを使用し、代わりに Uri.EscapeDataString-少なくとも理解できる動作をしていること。

どれどれ...

HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
                                  //standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
                                        // want, since you still need to
                                        // escape special characters yourself

しかし、私の個人的なお気に入りはHttpUtility.UrlPathEncodeでなければなりません-このことは本当に分かりにくいです。以下をエンコードします:

  • "" ==> "%20"
  • "100%true" ==> "100 %% 20true"(わかりました、あなたのURLは壊れています)
  • "test A.aspx#anchor B" ==> "test%20A.aspx#anchor%20B
  • "test A.aspx?hmm#anchor B" ==> "test%20A.aspx?hmm#アンカーB"(前のエスケープシーケンスとの違いに注意してください!

また、「Webサーバーからクライアントへの信頼性の高いHTTP転送のために、URL文字列のパス部分をエンコードする」という非常に具体的なMSDNドキュメントがあります。 -実際にそれが何をするのか説明せずに。あなたはウジで足で自分を撃つ可能性が低くなります...

つまり、ri.EscapeDataStringに固執します。

253
Eamon Nerbonne

これが最初に尋ねられてからほぼ9年が経ち、.NET Coreと.NET Standardの世界では、URLエンコードの最も一般的なオプションはWebUtility.UrlEncodeですSystem.Netの下)およびUri.EscapeDataString。ここと他の場所で最も一般的な答えから判断すると、Uri.EscapeDataStringが望ましいようです。しかし、それは?違いを理解するためにいくつかの分析を行いましたが、ここに私が思いついたものがあります:

  • WebUtility.UrlEncodeは、スペースを+としてエンコードします。 Uri.EscapeDataStringは、それを%20としてエンコードします。
  • Uri.EscapeDataString percent-encodes !()、および*; WebUtility.UrlEncodeはしません。
  • WebUtility.UrlEncode percent-encodes ~; Uri.EscapeDataStringはしません。
  • Uri.EscapeDataStringは、65,520文字より長い文字列に対してUriFormatExceptionをスローします。 WebUtility.UrlEncodeはしません。 ( 特にURLエンコードされたフォームデータを処理する場合は、考えられるよりも一般的な問題 。)
  • Uri.EscapeDataStringは、 高サロゲート文字 ;でUriFormatExceptionをスローします。 WebUtility.UrlEncodeはしません。 (これはUTF-16のもので、おそらくあまり一般的ではありません。)

URLエンコードの目的で、文字は次の3つのカテゴリのいずれかに適合します。予約済み(合法ですが、特別な意味があるため、mightエンコードしたい);その他すべて(常にエンコードする必要があります)。

RFC によると、予約文字は次のとおりです::/?#[]@!$&'()*+,;=

また、予約されていない文字は英数字と-._~です

評決

Uri.EscapeDataStringは、その使命を明確に定義しています。すべての予約文字と不正文字を%エンコードします。 WebUtility.UrlEncodeは、定義と実装の両方でより曖昧です。奇妙なことに、一部の予約文字をエンコードしますが、他の文字はエンコードしません(括弧でなく括弧を使用するのはなぜですか?)、そして、見知らぬ人はまだ無邪気に予約されていない~文字をエンコードします。

したがって、私は一般的なアドバイスに同意します-可能な場合はUri.EscapeDataStringを使用し、/?などの予約文字がエンコードされることを理解します。特にURLエンコードされたフォームコンテンツで、潜在的に大きな文字列を処理する必要がある場合は、WebUtility.UrlEncodeにフォールバックして受け入れる必要があります。その癖、またはそうでなければ問題を回避します。


EDIT:私は 試行Flurl で上記のすべての癖を修正しましたUrl.EncodeUrl.EncodeIllegalCharacters、およびUrl.Decode静的メソッド。これらは コアパッケージ (これは非常に小さく、すべてのHTTPを含むわけではありません)にあるか、ソースから自由にリッピングできます。これらについてのコメント/フィードバックを歓迎します。


以下は、どの文字が異なる方法でエンコードされているかを発見するために使用したコードです。

var diffs =
    from i in Enumerable.Range(0, char.MaxValue + 1)
    let c = (char)i
    where !char.IsHighSurrogate(c)
    let diff = new {
        Original = c,
        UrlEncode = WebUtility.UrlEncode(c.ToString()),
        EscapeDataString = Uri.EscapeDataString(c.ToString()),
    }
    where diff.UrlEncode != diff.EscapeDataString
    select diff;

foreach (var diff in diffs)
    Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
44
Todd Menier

おそらく、これらの方法のいずれも使用しないでください。 Microsoftの Anti-Cross Site Scripting Library には、より標準準拠で安全なHttpUtility.UrlEncodeおよびHttpUtility.HtmlEncodeの代替が含まれています。ボーナスとして、JavaScriptEncodeメソッドも取得します。

26
Joel Mueller

Server.UrlEncode()は、クラシックASPとの後方互換性を提供するためにあります。

Server.UrlEncode(str);

以下と同等です:

HttpUtility.UrlEncode(str, Response.ContentEncoding);
10
CMS

同じ、Server.UrlEncode()HttpUtility.UrlEncode()を呼び出します

4
andleer