2010-09-09 78 views
9

我需要一个Uri验证方法。因此,像字符串:从字符串验证Uri

http://www.google.com”, “www.google.com”, “google.com”

..must验证为的URI。而像“google”这样的普通字符串也不能作为Uri的验证。 要做这个检查,我使用了两种方法:UriBuilder和Uri.TryCreate()。

UriBuilder的问题是,我给它的任何字符串,它会返回一个Uri。当我在构造函数中传递一个普通字符串时,它会给出一个方案并返回“http://google/”,这不是我想要的行为。

Uri.TryCreate()的问题在于,虽然它可以与“http://www.google.com”和“www.google.com”正常工作,但当我将其设置为“google.com”时,它不会验证是否为Uri。

我考虑过对字符串进行检查,如果它以http://或www开头,则将字符串发送到UriBuilder类,但这对于“google.com”也没有帮助,它也必须是Uri。

如何验证诸如“google.com”之类的东西作为Uri,而不是“google”?检查.com,.net,.org字符串的结尾似乎不灵活。

+2

您可以验证您是否正在验证URL或URI吗?你的问题有点令人困惑。 – slugster 2010-09-09 07:12:15

+0

@Slugster - 在阅读完您的问题后,我在网上查询了解差异,所以答案是我需要验证一个URI而不是URL。 – 2010-09-09 12:14:40

回答

5
public static bool IsValidUri(string uriString) 
{ 
    Uri uri; 
    if (!uriString.Contains("://")) uriString = "http://" + uriString; 
    if (Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out uri)) 
    { 
     if (Dns.GetHostAddresses(uri.DnsSafeHost).Length > 0) 
     { 
      return true; 
     } 
    } 
    return false; 
} 
+1

该协议可以是除HTTP之外的其他一些内容(http://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Examples_of_absolute_URIs)。 – slugster 2010-09-09 07:04:39

+0

@slugster:这就是为什么他会检查它是否已经有一个协议......他只会将它设置为http,如果它不是......这是迄今为止最常见的并且对默认情况非常安全。 – mpen 2010-09-09 07:54:01

+0

谢谢你的代码。然而,这段代码从一个单词构建了一个Uri - 如果我通过“谷歌”,我得到了“http:// google /”,这不是我所需要的。另外我想避免在try/catch结构上构建代码逻辑。 – 2010-09-09 12:41:23

15

你在找什么是Uri.IsWellFormedUriString。下面的代码返回true:

Uri.IsWellFormedUriString("google.com", UriKind.RelativeOrAbsolute) 

如果设置UriKind为Absolute,则返回false:

Uri.IsWellFormedUriString("google.com", UriKind.Absolute) 

编辑: 见here为UriKind枚举。

  • RelativeOrAbsolute:Uri的类型是不确定的。
  • 绝对:Uri是绝对的Uri。
  • 相对:Uri是相对的Uri。

MSDN documentation

绝对URI的特征在于一个完整参考资源(例如:http://www.contoso.com/index.html),而相对URI取决于先前定义的基URI(例如:/index.html )。

另外,对于Uri.IsWellFormedUriString,参见here。此方法符合RFC 2396和RFC 2732.

如果您查看RFC 2396,您会看到google.com不是有效的URI。事实上,www.google.com并不是。但下F.缩网址,这situtation进行详细说明如下:

URL语法是专为明确的参考网络 资源和可扩展性通过URL方案。然而,随着URL 的识别和使用已经变得司空见惯,传统媒体 (电视,广播,报纸,广告牌等)已经越来越多地使用缩写的URL引用。也就是说,由 组成的参考仅包括所标识的资源的权威和路径部分,诸如 如 www.w3.org/Addressing/ 或者仅仅是DNS主机名。这样的参考主要是用于人类解释而不是机器的 ,其中 假设基于上下文的启发式就足以完成 的URL(例如,以“www”开头的大多数主机名可能具有 的URL前缀“http ://“)。虽然没有标准的 启发式来区分缩写的URL引用,但许多客户端实现允许用户输入它们并且启发式地解析 。应该指出的是,这种启发式可能会随着时间的推移而变化,特别是当引入新的URL方案时。 由于缩写的URL与相对URL路径具有相同的语法,因此在需要相对 URL的上下文中不能使用缩写的URL引用。这限制了使用缩略网址的地方 没有定义的基本URL,如对话框和离线 广告。

我的理解是,Uri.IsWellFormedUriString接受形式为www.abc.com的字符串作为有效的URI。但是google.com不被接受为绝对URI,而是被接受为相对URI,因为它符合相对路径规范(路径可以包含。)。另外,作为一个附注,如果您想使用正则表达式来解析URI,您可以阅读B.使用正则表达式解析URI引用

+0

谢谢你的回答。这种方法很有趣,它确实验证了“google.com”,但它验证了一个单词(“google”)是一个很好的uri,我也不需要。 – 2010-09-09 12:32:38

+0

@Andrei:我已经更新了我的答案。答案在于RFC 2396. – Zafer 2010-09-09 13:29:07

+0

感谢你们,我进一步阅读了关于Uri.IsWellFormedUriString的内容,我想我明白为什么它将“google”验证为有效的Uri。所以,我想我需要的是检查字符串末尾是否附有.com,.net,..etc的方法。我不愿意使用Regular Exp,因为它们可能存在缺陷,如果将来有人发明了像.zedo这样的流行扩展,例如我的regExp不会捕获它,因为它只能处理已知的终止(.net, .com等)。 – 2010-09-09 16:26:04

2

为此使用RegExp。验证URL

Regex RgxUrl = new Regex("(([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?"); 
    if (RgxUrl.IsMatch(<yourURLparameter>)) 
    { 
     //url is valid 
    } 
    else 
    { 
     //url is not valid 
    } 
3

如此

示例代码是从Jojaba我向他们感谢的DNS检查代码的变种,这是我需要的东西。唯一的问题是它在我希望避免的逻辑中使用try catch。

 public static Uri StringToAbsoluteUri(string uriString) 
     { 
     Uri resultUri = null; 

     if (!uriString.Contains(Uri.SchemeDelimiter)) 
      uriString = Uri.UriSchemeHttp + Uri.SchemeDelimiter + uriString; 

     if (Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out resultUri)) 
     { 
      try 
      { 
       IPAddress[] addressesOfHost = Dns.GetHostAddresses(resultUri.DnsSafeHost); 
       if (addressesOfHost.Length > 0) 
       { 
        return resultUri; 
       } 
      } 
      catch (System.Net.Sockets.SocketException) 
      { 
       return null; 
      } 
     } 
     return resultUri; 
     }