web-dev-qa-db-ja.com

末尾にスラッシュがないベースUri

次のようにUriを使用してUriBuilderを作成すると、

var rootUrl = new UriBuilder("http", "example.com", 50000).Uri;

その場合、AbsoluteUrirootUrlには、常に次のような末尾のスラッシュが含まれます。

http://example.com:50000/

私が望むのは、末尾のスラッシュなしでUriオブジェクトを作成することですが、それは不可能のようです。

私の回避策は、代わりに文字列として格納し、次のような醜いことをすることです:

var rootUrl = new UriBuilder("http", "example.com", 50000).Uri.ToString().TrimEnd('/');

スラッシュがなければウリは無効であると人々が言うのを聞いたことがあります。それは本当ではないと思います。私はRFC 3986を調べましたが、セクション3.2.2では次のように述べています。

URIに機関コンポーネントが含まれている場合、パスコンポーネントは空であるか、スラッシュ( "/")文字で始まる必要があります。

末尾のスラッシュが存在しなければならないということではありません。

10
4thex

末尾のスラッシュは、任意のURIではrequiredではありませんが、リクエストの絶対URIのcanonical表現の一部です in HTTP

絶対パスを空にすることはできません。元のURIに何も存在しない場合は、「/」(サーバールート)として指定する必要があります。

仕様 を守るために、Uriクラスは、末尾にスラッシュを付けた形式でURIを出力します。

一般に、空のパスを持つ権限の一般的な構文を使用するURIは、「/」のパスに正規化する必要があります。

この動作は、.NETのUriオブジェクトでは構成できません。 Webブラウザーと多くのHTTPクライアントは、パスが空のURLのリクエストを送信するときに同じ書き換えを実行します。

URLを文字列ではなくUriオブジェクトとして内部的に表現する場合は、末尾のスラッシュなしでURLをフォーマットする extension method を作成できます。これにより、このプレゼンテーションロジックが抽象化されます。表示用のURLを出力する必要があるたびに複製するのではなく、1つの場所:

namespace Example.App.CustomExtensions 
{
    public static class UriExtensions 
    {
        public static string ToRootHttpUriString(this Uri uri) 
        {
            if (!uri.IsHttp()) 
            {
                throw new InvalidOperationException(...);
            }

            return uri.Scheme + "://" + uri.Authority;
        }

        public static bool IsHttp(this Uri uri) 
        {
            return uri.Scheme == "http" || uri.Scheme == "https";
        }
    }
}

次に:

using Example.App.CustomExtensions;
...

var rootUrl = new UriBuilder("http", "example.com", 50000).Uri; 
Console.WriteLine(rootUrl.ToRootHttpUriString()); // "http://example.com:50000"
7
Cy Rossignol

Uri.GetComponents 方法:

rootUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.UriEscaped)

stringの異なるコンポーネントのUri表現を返します。この場合はUriComponents.SchemeAndServerは、schemeHost、およびportコンポーネント。

あなたはそれについてMSDNでもっと読むことができます:

  1. ri.GetComponents

  2. riComponents

  3. riFormat

2
eitamal