文字列からUriを作成するには、次のようにします。
Uri u = new Uri("example.com");
ただし、問題は、文字列(上記のような)にプロトコルが含まれていない場合、例外が発生することです: "Invalid URI: The format of the URI could not be determined.
"
例外を回避するには、次のようなプロトコルを含む文字列を保護する必要があります。
Uri u = new Uri("http://example.com");
しかし、入力としてURLを使用する場合、欠落しているプロトコルをどのように追加できますか?
IndexOf/Substringの操作とは別の意味ですか?
エレガントで高速なものですか?
UriBuilder
を使用することもできます。
public static Uri GetUri(this string s)
{
return new UriBuilder(s).Uri;
}
MSDNからのコメント:
このコンストラクターは、UriBuilderクラスの新しいインスタンスを、uriで指定されたように設定されたFragment、Host、Path、Port、Query、Scheme、およびUriプロパティで初期化します。
uriがスキームを指定しない場合、スキームはデフォルトで「http:」になります。
URLを検証せずにスキームを追加するだけの場合、最速/最も簡単な方法は、文字列検索を使用することです。例:
string url = "mydomain.com";
if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase)) url = "http://" + url;
より良い方法は、 Uri
を使用して TryCreate
メソッドを使用してURLを検証することです。
string url = "mydomain.com";
Uri uri;
if ((Uri.TryCreate(url, UriKind.Absolute, out uri) || Uri.TryCreate("http://" + url, UriKind.Absolute, out uri)) &&
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
{
// Use validated URI here
}
@JanDavidNarkiewiczがコメントで指摘したように、Scheme
の検証は、スキームなしでポートが指定されている場合に無効なスキームを防ぐために必要です。 mydomain.com:80
。
私の解決策は、プロトコルが正規表現であることを確認するためのプロトコールレスURLです:
Regex.Replace(s, @"^\/\/", "http://");
Localhost:8800などのようなものを入力するための従来の許可がある特定のケースがありました。つまり、それを解析する必要がありました。 URIを非常に大まかに指定する可能性を分離するもう少し手の込んだParseUriメソッドを構築しましたが、人々が非標準のスキーム(およびIPロング表記のホストも指定する場合もあるため)を指定する時間もキャッチしました
UriBuilderと同様に、何も指定されていない場合、デフォルトでhttpスキームが使用されます。基本認証が指定され、パスワードが数字のみで構成されている場合、問題が発生します。 (そのコミュニティを修正してください)
private static Uri ParseUri(string uri)
{
if (uri.StartsWith("//"))
return new Uri("http:" + uri);
if (uri.StartsWith("://"))
return new Uri("http" + uri);
var m = System.Text.RegularExpressions.Regex.Match(uri, @"^([^\/]+):(\d+)(\/*)", System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline);
if (m.Success)
{
var port = int.Parse(m.Groups[2].Value);
if (port <= 65535) //part2 is a port (65535 highest port number)
return new Uri("http://" + uri);
else if (port >= 16777217) //part2 is an ip long (16777217 first ip in long notation)
return new UriBuilder(uri).Uri;
else
throw new ArgumentOutOfRangeException("Invalid port or ip long, technically could be local network hostname, but someone needs to be hit on the head for that one");
}
else
return new Uri(uri);
}