如何检查URI字符串是否有效


79

如何检查uri字符串是否有效(可以将其提供给Uri构造函数)?

到目前为止,我只有以下几种,但出于明显的原因,我宁愿使用一种不太粗暴的方法:

    Boolean IsValidUri(String uri)
    {
        try
        {
            new Uri(uri);
            return true;
        }
        catch
        {
            return false;
        }
    }

我试过了Uri.IsWellFormedUriString,但是它似乎并不喜欢您可以扔给构造函数的所有东西。例如:

String test = @"C:\File.txt";
Console.WriteLine("Uri.IsWellFormedUriString says: {0}", Uri.IsWellFormedUriString(test, UriKind.RelativeOrAbsolute));
Console.WriteLine("IsValidUri says: {0}", IsValidUri(test));

输出将是:

Uri.IsWellFormedUriString says: False
IsValidUri says: True

更新/回答

默认情况下,Uri构造函数使用种类Absolute。当我尝试使用Uri.TryCreate和构造函数时,这导致了差异。如果为构造函数和TryCreate都匹配UriKind,则可以得到预期的结果。

Answers:


80

格式正确的URI表示符合某些RFC。您的示例中的本地路径与此不一致。在IsWellFormedUriString文档中阅读更多内容。

该方法的错误结果并不表示Uri该类将无法解析输入。尽管URI输入可能不符合RFC,但仍然可以是有效的URI。

更新:并回答您的问题-正如Uri文档所示,有一个名为的静态方法TryCreate,它将尝试您所需要的,并返回true或false(Uri如果为true ,则返回实际实例)。


问题是“如何检查uri字符串是否有效(可以将其提供给Uri构造函数)?”
曼努埃尔

1
TryCreate并没有真正告诉您构造函数是否接受字符串。请参阅更新。
曼努埃尔

@Manuel:根本没有意义-TryCreate和的Uri构造函数的结果应该相同-尝试UriKind像您一样传递TryCreate
BrokenGlass

1
你是对的。构造函数使用默认种类Absolute。谢谢。
曼努埃尔

3
根据.Net消息,IsWellFormedUriString方法包含TryCreate方法调用以及额外的检查,因此,我更喜欢将IsWellFormedUriString方法用于此类任务,因为它功能更强大。
伊戈尔·库斯托夫

43

由于接受的答案没有提供明确的示例,因此下面是一些用于验证C#中URI的代码:

Uri outUri;

if (Uri.TryCreate("ThisIsAnInvalidAbsoluteURI", UriKind.Absolute, out outUri)
   && (outUri.Scheme == Uri.UriSchemeHttp || outUri.Scheme == Uri.UriSchemeHttps))
{
    //Do something with your validated Absolute URI...
}

2
不要相信Uri.TryCreate函数!这也将允许错误的URL。试试这个“ http:// http:// google.com/page”(删除空格)。该URL传递了TryCreate函数,但这是错误的。
No1Lives4Ever

5
@ No1Lives4Ever您将其解析为您所说的有效是正确的,但是从技术上来说这不是错误的。英文说明:使用http协议(http://),使用显式(但省略)端口(http **:* )连接到“ http”(http:// ** http **)的DNS条目*)-因此,我假设该协议为默认协议;您提供了一个空的第一级文件夹(http:** // **),但我知道您的意思;),然后是路径段“ google.com”(http:/ ** google.com / **),然后资源“页面”(http://google.com **页面**)
mlhDev

9

假设我们只想支持绝对URI和HTTP请求,则此函数可以满足您的要求:

public static bool IsValidURI(string uri)
{
    if (!Uri.IsWellFormedUriString(uri, UriKind.Absolute))
        return false;
    Uri tmp;
    if (!Uri.TryCreate(uri, UriKind.Absolute, out tmp))
        return false;
    return tmp.Scheme == Uri.UriSchemeHttp || tmp.Scheme == Uri.UriSchemeHttps;
}


1
需要进行第二次检查才能进行第三次(也是最后一次)检查。没有它,就没有tmp。在这种情况下,第一步可能是多余的……
Joe


0

在您的情况下,uri参数是指向文件位置的绝对路径,因此根据该方法的文档,它返回false。参考这个


我正在使用UriKind.RelativeOrAbsolute,所以不要紧。无论哪种方式,它都不能与UriKind.Relative或UriKind.Absolute一起使用,因此在那里没有运气。
曼努埃尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.