Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果需要,将方案添加到URL_C#_.net_Uri - Fatal编程技术网

C# 如果需要,将方案添加到URL

C# 如果需要,将方案添加到URL,c#,.net,uri,C#,.net,Uri,要从字符串创建Uri,可以执行以下操作: Uri u = new Uri("example.com"); 但问题是,如果字符串(如上面的字符串)不包含协议,您将得到一个异常:“无效URI:无法确定URI的格式。” 为避免出现异常,应确保字符串包含协议,如下所示: Uri u = new Uri("http://example.com"); 但是如果您将url作为输入,如果缺少协议,如何添加协议? 我的意思是除了一些索引/子字符串操作之外 优雅快速的东西?您也可以使用: MSDN的备注: 此构

要从字符串创建Uri,可以执行以下操作:

Uri u = new Uri("example.com");
但问题是,如果字符串(如上面的字符串)不包含协议,您将得到一个异常:“
无效URI:无法确定URI的格式。

为避免出现异常,应确保字符串包含协议,如下所示:

Uri u = new Uri("http://example.com");
但是如果您将url作为输入,如果缺少协议,如何添加协议?
我的意思是除了一些索引/子字符串操作之外

优雅快速的东西?

您也可以使用:

MSDN的备注:

此构造函数使用Uri中指定的片段、主机、路径、端口、查询、方案和Uri属性集初始化UriBuilder类的新实例

如果uri未指定方案,则方案默认为“http:”。


我的解决方案是使用protocall-less URL,以确保它们具有protocal-was-regex:

Regex.Replace(s, @"^\/\/", "http://");

如果只想添加方案而不验证URL,最快/最简单的方法是使用字符串查找,例如:

string url = "mydomain.com";
if (!url.StartsWith("http://", StringComparison.OrdinalIgnoreCase)) url = "http://" + url;
更好的方法是使用以下方法验证URL:


正如@JanDavidNarkiewicz在评论中指出的,当指定的端口没有Scheme时,验证
Scheme
是必要的,以防止无效的Scheme,例如
mydomain.com:80

我们有一些特定的情况,其中有一个遗留的允许输入内容,例如: 本地主机:8800或类似。这意味着我们需要分析它。我们构建了一个更加复杂的ParseUri方法,该方法将指定URI的可能性分离得非常松散,但也抓住了人们指定非标准方案(以及IP长表示法中的主机,因为有时人们会这样做)的时机

与UriBuilder一样,如果未指定任何内容,它将默认为http方案。如果指定了基本身份验证且密码仅由数字组成,则会出现问题。(请随意修复该社区)

私有静态Uri解析Uri(字符串Uri)
{
if(uri.StartsWith(“/”)
返回新的Uri(“http:+Uri”);
if(uri.StartsWith(“:/”)
返回新的Uri(“http”+Uri);
var m=System.Text.RegularExpressions.Regex.Match(uri,@“^([^\/]):(\d+)(\/*)”,System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline);
如果(m.成功)
{
var port=int.Parse(m.Groups[2].Value);
if(port=16777217)//第2部分是一个ip长(16777217长符号中的第一个ip)
返回新的UriBuilder(uri).uri;
其他的
抛出新的ArgumentOutOfRangeException(“无效端口或ip长,从技术上讲可能是本地网络主机名,但需要有人为此受到打击”);
}
其他的
返回新的Uri(Uri);
}

有趣的是,尽管
Uri
UriBuilder
在没有方案的情况下完全破坏了任何url,
WebProxy
做得不错

所以只要打电话:

new WebProxy(proxy.ProxyServer).Address

IndexOf
应该足够快;“计划”。。。非“协议”这表示,当您尝试使用诸如“//domain.com”之类的无协议调用url时,主机名无法解析。请小心使用:使用诸如
stackoverflow.com:80
之类的端口进行输入,解析时不会出错,但会被解释为
Scheme:stackoverflow.com
Path:80
端口:-1
。与预期的不完全一样……如果方案缺失,则此方法有效。如果主机名也丢失(例如,
/foo/bar
),这将抛出“无效URI:无法解析主机名”。由于一个非常微妙的问题,这种方法将无法工作:带有端口的url(“mydomain.com:8080”)在传递给TryCreate时将返回true。Uri的方案是mydomain.com。“您认为Uri类有一个bug,但它高于m pay grade。@JanDavidNarkiewicz您是正确的,这可能是因为
mailto:
tel:
也是有效的方案,端口分隔符被视为方案分隔符。”。我已经更新了代码来防止这种情况@只有当您确定URL支持HTTPS时,才能使用S.Serpooshan。。。因此,最安全的方法是默认使用HTTP(就像浏览器、编辑器等一样)!此正则表达式仅测试字符串开头是否有双斜杠
/
,例如
www.stackoverflow.com
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
}
new WebProxy(proxy.ProxyServer).Address