この記事では、この API のリファレンス ドキュメントに補足的な解説を提供します。
UNIFORM Resource Identifier (URI) は、イントラネットまたはインターネット上のアプリケーションで使用できるリソースのコンパクトな表現です。 Uri クラスは、解析、比較、結合など、URI を処理するためのプロパティとメソッドを定義します。 Uri クラスのプロパティは読み取り専用です。変更可能なオブジェクトを作成するには、UriBuilder クラスを使用します。
相対 URI ("/new/index.htm"など) は、基本 URI に対して展開して、絶対 URI になるようにする必要があります。 MakeRelativeUriメソッドは、必要に応じて絶対 URI を相対 URI に変換するために提供されます。
文字列がスキーム識別子を含む整形式 URI の場合、 Uri コンストラクターは URI 文字列をエスケープしません。
Uriプロパティは、エスケープエンコードで正規のデータ表現を返し、Unicode 値が 127 より大きいすべての文字は 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 に従ってエスケープされます。 この動作は、国際リソース識別子または国際ドメイン名の解析が有効になっている場合に、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 メソッドを使用して、ToString クラスの内容をエスケープ エンコードされた URI 参照から読み取り可能な URI 参照に変換できます。 ToString メソッドの出力では、一部の予約文字がエスケープされる可能性があることに注意してください。 これは、 ToStringによって返される値からの URI の明確な再構築をサポートするためです。
一部の URI には、フラグメント識別子またはクエリ、またはその両方が含まれます。 フラグメント識別子は、番号記号 (#)の後に続く任意のテキストであり、番号記号は含まれません。フラグメント テキストは、 Fragment プロパティに格納されます。 クエリ情報は、URI の疑問符 (?) に続くテキストです。クエリ テキストは、 Query プロパティに格納されます。
注
URI クラスでは、IPv4 プロトコルのクワッド表記と IPv6 プロトコルのコロン 16 進数の両方での IP アドレスの使用がサポートされています。 http://[::1]のように、IPv6 アドレスは角かっこで囲んでください。
国際リソース識別子のサポート
Web アドレスは通常、非常に制限された文字セットで構成される URI を使用して表されます。
- 英字の大文字と小文字の 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 ファイルで構成オプションを設定して、国際化ドメイン名 (IDN) 解析をドメイン名に適用するかどうかを指定できます。 例えば次が挙げられます。
<configuration>
<uri>
<idn enabled="All" />
</uri>
</configuration>
IDN を有効にすると、ドメイン名内のすべての Unicode ラベルが、対応する Punycode に変換されます。 Punycode 名には ASCII 文字のみが含まれ、常に xn-- プレフィックスで始まります。 これは、ほとんどの DNS サーバーが ASCII 文字のみをサポートするため、インターネット上の既存の DNS サーバーをサポートするためです (RFC 3940 を参照)。
IDN を有効にすると、 Uri.DnsSafeHost プロパティの値に影響します。 IDN を有効にすると、 Equals、 OriginalString、 GetComponents、および IsWellFormedOriginalString メソッドの動作も変更できます。
IDN には、使用される DNS サーバーに応じて、次の 3 つの値を指定できます。
idn 有効化 = 全て
Unicode ドメイン名を、対応する Punycode (IDN 名) に変換します。
idn enabled = すべて許可(イントラネットを除く)
ローカル イントラネット上にないすべての Unicode ドメイン名を、同等の Punycode (IDN 名) を使用するように変換します。 この場合、ローカル イントラネット上の国際名を処理するには、イントラネットに使用される DNS サーバーで Unicode 名前解決をサポートする必要があります。
IDN enabled = なし
Punycode を使用するように Unicode ドメイン名は変換されません。 これが既定値です。
正規化と文字チェックは、RFC 3986 および RFC 3987 の最新の IRI 規則に従って行われます。
Uri クラスの IRI および IDN 処理は、System.Configuration.IriParsingElement、System.Configuration.IdnElement、およびSystem.Configuration.UriSection構成設定クラスを使用して制御することもできます。 System.Configuration.IriParsingElement設定では、Uri クラスでの IRI 処理を有効または無効にします。 System.Configuration.IdnElement設定では、Uri クラスでの IDN 処理を有効または無効にします。
System.Configuration.IriParsingElementとSystem.Configuration.IdnElementの構成設定は、最初のSystem.Uri クラスが構築されるときに 1 回読み取られます。 その後の構成設定の変更は無視されます。
System.GenericUriParser クラスも拡張され、IRI と IDN をサポートするカスタマイズ可能なパーサーを作成できます。 System.GenericUriParser オブジェクトの動作は、System.GenericUriParserOptions列挙で使用可能な値のビットごとの組み合わせをSystem.GenericUriParserコンストラクターに渡すことによって指定されます。 GenericUriParserOptions.IriParsing型は、パーサーが RFC 3987 で国際リソース識別子 (IRI) に指定されている解析規則をサポートすることを示します。
GenericUriParserOptions.Idn型は、パーサーがホスト名の国際化ドメイン名 (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 として解釈します。
セキュリティに関する考慮事項
セキュリティ上の懸念から、信頼できないソースから Uri インスタンスを受け取り、dontEscape
で 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 が必要なときに、アプリケーションの影響を受ける部分を初期化します。開始時刻には初期化しません。
.NET