System.Uri クラス

この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。

URI は、イントラネットまたはインターネット上のアプリケーションで使用できるリソースのコンパクトな表現です。 このクラスは Uri 、解析、比較、結合など、URI を処理するためのプロパティとメソッドを定義します。 クラス プロパティは Uri 読み取り専用です。変更可能なオブジェクトを作成するには、クラスを UriBuilder 使用します。

相対 URI ("/new/index.htm" など) は、ベース URI に対して展開して、絶対 URI になるようにする必要があります。 この MakeRelativeUri メソッドは、必要に応じて絶対 URI を相対 URI に変換するために提供されます。

文字列が Uri スキーム識別子を含む整形式の URI である場合、コンストラクターは URI 文字列をエスケープしません。

プロパティは Uri 、127 より大きい Unicode 値を持つすべての文字を 16 進数に置き換えて、エスケープエンコードで正規のデータ表現を返します。 URI を正規形式で配置するために、コンストラクターは Uri 次の手順を実行します。

  • URI スキームを小文字に変換します。

  • ホスト名を小文字に変換します。

  • ホスト名が IPv6 アドレスの場合は、正規の IPv6 アドレスが使用されます。 ScopeId およびその他のオプションの IPv6 データが削除されます。

  • 既定のポート番号と空のポート番号を削除します。

  • file:// スキームのない暗黙的なファイル パス ("C:\my\file" など) を、file:// スキームを使用して明示的なファイル パスに変換します。

  • 予約目的を持たないエスケープ文字 (パーセントエンコードオクテットとも呼ばれます) はデコードされます (エスケープ解除とも呼ばれます)。 これらの予約されていない文字には、大文字と小文字 (%41-%5A および %61-%7A)、10 進数 (%30-%39)、ハイフン (%2D)、ピリオド (%2E)、アンダースコア (%5F)、チルダ (%7E) が含まれます。

  • /./、/. などのシーケンスを圧縮して、階層 URI のパスを正規化します。/、および // (シーケンスがエスケープされているかどうか)。 これらのシーケンスが圧縮されないスキームがあることに注意してください。

  • 階層 URI の場合、ホストがスラッシュ (/) で終了しない場合は、1 つが追加されます。

  • 既定では、URI 内の予約文字はすべて RFC 2396 に従ってエスケープされます。 この動作は、国際リソース識別子または International Doメイン 名前の解析が有効になっている場合に、RFC 3986 および RFC 3987 に従って URI 内の予約文字がエスケープされる場合に変更されます。

一部のスキームのコンストラクターでの正規化の一環として、ドット セグメントと空のセグメント (/.//../および //) が圧縮されます (つまり、削除されます)。 セグメントを圧縮する Uri スキームには、http、https、tcp、net.pipe、および net.tcp が含まれます。 その他のスキームでは、これらのシーケンスは圧縮されません。 次のコード スニペットは、実際の圧縮の外観を示しています。 エスケープされたシーケンスは、必要に応じてエスケープ解除され、圧縮されます。

var uri = new Uri("http://myUrl/../.."); // http scheme, unescaped
OR
var uri = new Uri("http://myUrl/%2E%2E/%2E%2E"); // http scheme, escaped
OR
var uri = new Uri("ftp://myUrl/../.."); // ftp scheme, unescaped
OR
var uri = new Uri("ftp://myUrl/%2E%2E/%2E%2E"); // ftp scheme, escaped

Console.WriteLine($"AbsoluteUri: {uri.AbsoluteUri}");
Console.WriteLine($"PathAndQuery: {uri.PathAndQuery}");

このコードを実行すると、次のテキストのような出力が返されます。

AbsoluteUri: http://myurl/
PathAndQuery: /

メソッドを使用して、エスケープエンコードされた URI 参照から読み取り可能な URI 参照にクラスの内容 UriToString 変換できます。 一部の予約文字は、メソッドの ToString 出力でエスケープされる可能性があることに注意してください。 これは、によって返される値からの URI の明確な再構築をサポートするため ToStringです。

一部の URI には、フラグメント識別子またはクエリ、またはその両方が含まれます。 フラグメント識別子は、番号記号 (#)の後に続く任意のテキストであり、番号記号は含まれません。フラグメント テキストはプロパティに Fragment 格納されます。 クエリ情報は、URI の疑問符 (?) に続くテキストです。クエリ テキストはプロパティに Query 格納されます。

Note

URI クラスでは、IPv4 プロトコルのクワッド表記と IPv6 プロトコルのコロン 16 進数の両方での IP アドレスの使用がサポートされています。 http://[::1]のように、IPv6 アドレスは角かっこで囲んでください。

国際リソース識別子のサポート

Web アドレスは、通常、非常に制限された文字セットで構成される一様なリソース識別子を使用して表されます。

  • 英文字の大文字と小文字の ASCII 文字。
  • 0 から 9 の数字。
  • その他の少数の ASCII シンボル。

URI の仕様は、インターネット エンジニアリング タスク フォース (IETF) によって公開されている RFC 2396、RFC 2732、RFC 3986、RFC 3987 に記載されています。

英語以外の言語を使用してリソースを識別し、非 ASCII 文字 (Unicode/ISO 10646 文字セットの文字) を許可する必要がある識別子は、国際リソース識別子 (IRI) と呼ばれます。 IRI の仕様は、IETF によって発行された RFC 3987 で規定されています。 IRI を使用すると、URL に Unicode 文字を含めることができます。

.NET Framework 4.5 以降のバージョンでは、IRI は常に有効になっており、構成オプションを使用して変更することはできません。 machine.config または app.config ファイルで構成オプションを設定して、国際化 Doメイン Name (IDN) 解析を doメイン 名に適用するかどうかを指定できます。 次に例を示します。

<configuration>
  <uri>
    <idn enabled="All" />
  </uri>
</configuration>

IDN を有効にすると、doメイン 名内のすべての Unicode ラベルが、対応する Punycode に変換されます。 Punycode 名には ASCII 文字のみが含まれ、常に xn-- プレフィックスで始まります。 この理由は、ほとんどの DNS サーバーは ASCII 文字しかサポートしていないため、インターネットで既存の DNS サーバーをサポートするためです (RFC 3940 を参照)。

IDN を有効にすると、プロパティの値に影響します Uri.DnsSafeHost 。 IDN を有効にすると、メソッド 、、OriginalStringGetComponentsおよびIsWellFormedOriginalStringメソッドのEquals動作も変更できます。

IDN には、使用する DNS サーバーに応じて、次の 3 つの値を指定できます。

  • idn enabled = All

    この値は、Unicode のドメイン名があれば、それを等価の Punycode (IDN 名) に変換します。

  • idn enabled = AllExceptIntranet

    この値は、ローカル イントラネット上にないすべての Unicode ドメイン名を、等価の Punycode (IDN 名) を使用するように変換します。 このように、ローカルなイントラネットで国際名を処理する場合、このイントラネットで使用する DNS サーバーは Unicode 名の解決をサポートしている必要があります。

  • idn enabled = None

    この値は、どの Unicode のドメイン名も、Punycode を使用するように変換しません。 これが既定値です。

正規化と文字チェックは、RFC 3986 および RFC 3987 の最新の IRI 規則に従って行われます。

クラス内の Uri IRI および IDN 処理は、構成設定クラス、およびSystem.Configuration.UriSection構成設定クラスをSystem.Configuration.IriParsingElementSystem.Configuration.IdnElement使用して制御することもできます。 System.Configuration.IriParsingElement 設定は、Uri クラスでの IRI 処理を有効または無効にします。 System.Configuration.IdnElement 設定は、Uri クラスでの IDN 処理を有効または無効にします。

最初System.UriのクラスがSystem.Configuration.IriParsingElementSystem.Configuration.IdnElement構築されるときに 1 回読み取られます。 それ以降の構成設定の変更は無視されます。

IRI と IDN をサポートするカスタマイズ可能なパーサーを作成できるように、System.GenericUriParser クラスも拡張されています。 System.GenericUriParser オブジェクトの動作は、System.GenericUriParserOptions 列挙型で使用可能な値のビットごとの組み合わせを System.GenericUriParser コンストラクターに渡すことによって指定されます。 GenericUriParserOptions.IriParsing 型は、パーサーが International Resource Identifiers (IRI) の RFC 3987 で規定された解析規則をサポートしていることを示します。

この型はGenericUriParserOptions.Idn、パーサーがホスト名の国際化 Doメイン Name (IDN) 解析をサポートしていることを示します。 .NET 5 以降のバージョン (.NET Core を含む) と .NET Framework 4.5 以降では、IDN が常に使用されます。 以前のバージョンでは、構成オプションによって IDN が使用されるかどうかが決まります。

暗黙的なファイル パスのサポート

Uri は、ローカル ファイル システム パスを表すためにも使用できます。 これらのパスは、file:// スキームで始まる URI で明示的に表すことができます。また、file:// スキームを持たない URI では暗黙的にすことができます。 具体的な例として、次の 2 つの URI はどちらも有効であり、同じファイル パスを表します。

Uri uri1 = new Uri("C:/test/path/file.txt") // Implicit file path.
Uri uri2 = new Uri("file:///C:/test/path/file.txt") // Explicit file path.

これらの暗黙的なファイル パスは URI 仕様に準拠していないため、可能な場合は避ける必要があります。 Unix ベースのシステムで .NET Core を使用する場合、絶対暗黙的なファイル パスが相対パスと区別できないため、暗黙的なファイル パスが特に問題になる可能性があります。 このようなあいまいさが存在する場合、既定ではパス Uri が絶対 URI として解釈されます。

セキュリティに関する考慮事項

セキュリティ上の懸念があるため、アプリケーションでは、信頼されていないソースdontEscapeからインスタンスをUri受け入れるときに、コンストラクターに設定して慎重に使用するtrue必要があります。 メソッドを呼び出IsWellFormedOriginalStringすことで、URI 文字列を有効にチェックできます。

信頼されていないユーザー入力を処理する場合は、そのプロパティを信頼する前に、新しく作成された Uri インスタンスに関する前提条件を確認します。 これは、次の方法で実行できます。

string userInput = ...;

Uri baseUri = new Uri("https://myWebsite/files/");

if (!Uri.TryCreate(baseUri, userInput, out Uri newUri))
{
    // Fail: invalid input.
}

if (!baseUri.IsBaseOf(newUri))
{
    // Fail: the Uri base has been modified - the created Uri is not rooted in the original directory.
}

この検証は、UNC パスを処理する場合など、次のように単純に変更することで、他の場合に baseUri使用できます。

Uri baseUri = new Uri(@"\\host\share\some\directory\name\");

パフォーマンスに関する考慮事項

URI を含む Web.configファイルを使用してアプリケーションを初期化する場合、URI のスキーム識別子が標準でない場合は、URI の処理に追加の時間が必要です。 このような場合は、URI が必要なときに、アプリケーションの影響を受ける部分を初期化します。開始時刻には初期化しません。