C# 字符串是否为有效URL

C# 字符串是否为有效URL,c#,uri,C#,Uri,我正在使用.NET2010C#windows应用程序,代码如下:检查Uri是否有效 代码: static bool IsValidUrl(string urlString) { Uri uri; return Uri.TryCreate(urlString, UriKind.Absolute, out uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.Uri

我正在使用.NET2010C#windows应用程序,代码如下:检查Uri是否有效

代码:

static bool IsValidUrl(string urlString)
{
    Uri uri;
    return Uri.TryCreate(urlString, UriKind.Absolute, out uri)
        && (uri.Scheme == Uri.UriSchemeHttp
         || uri.Scheme == Uri.UriSchemeHttps
         || uri.Scheme == Uri.UriSchemeFtp
         || uri.Scheme == Uri.UriSchemeMailto
         );
}
问题:如果我验证此
http://http://www.Google.com
我得到了它的有效信息,但当我尝试使用IE时,它没有显示任何站点


有没有办法确定字符串是否是有效的uri?(不使用正则表达式和internet访问)

您可以编写一个自定义函数来检查http://或初始部分是否与您编写的代码一起重复。

了解给定字符串是否表示有效url的最佳方法是,无需实际测试,并且记住上面的注释(可能在给定的模式中适合的东西,但不是你认为正确的),是执行自定义分析。此外,你应该用<代码>字符串(或<代码> URI < /代码>)替换你的<代码> BoOL 函数,它能够纠正某些情况(如你提出的例子)。示例代码:

private void Form1_Load(object sender, EventArgs e)
{
    string rightUrl = returnValidUrl("http://http://www.Google.com");
    if (rightUrl != "")
    {
        //It is OK
    }
}

static string returnValidUrl(string urlString)
{
    string outUrl = "";
    Uri curUri = IsValidUrl(urlString);
    if (curUri != null)
    {
        string headingBit = "http://";
        if (curUri.Scheme == Uri.UriSchemeHttps) headingBit = "https://";
        if (curUri.Scheme == Uri.UriSchemeFtp) headingBit = "ftp://";
        if (curUri.Scheme == Uri.UriSchemeMailto) headingBit = "mailto:";

        outUrl = headingBit + urlString.ToLower().Substring(urlString.ToLower().LastIndexOf(headingBit) + headingBit.Length);
    }

    return outUrl;
}

static Uri IsValidUrl(string urlString)
{
    Uri uri = null;
    bool isValid = Uri.TryCreate(urlString, UriKind.Absolute, out uri)
        && (uri.Scheme == Uri.UriSchemeHttp
         || uri.Scheme == Uri.UriSchemeHttps
         || uri.Scheme == Uri.UriSchemeFtp
         || uri.Scheme == Uri.UriSchemeMailto
         );

    if (!isValid) uri = null;

    return uri;
}
可以通过以下方式调用:

string rightUrl = returnValidUrl("http://http://www.Google.com");
if (rightUrl != "")
{
    //It is OK
}
您必须扩展此方法以识别/纠正所有需要的情况

更新

根据评论和建议,为了提供OP正在寻找的确切功能(一个示例;只要建议的解决方案只是此问题所需的随意性方法类型的一个示例),考虑到发布的示例错误,这里您有一个已更正的
bool
功能:

static bool IsValidUrl2(string urlString)
{
    Uri uri;
    return Uri.TryCreate(urlString, UriKind.Absolute, out uri)
        && ((uri.Scheme == Uri.UriSchemeHttp && numberOfBits(urlString.ToLower(), "http://") == 1)
         || (uri.Scheme == Uri.UriSchemeHttps && numberOfBits(urlString.ToLower(), "https://") == 1)
         || (uri.Scheme == Uri.UriSchemeFtp && numberOfBits(urlString.ToLower(), "ftp://") == 1)
         || (uri.Scheme == Uri.UriSchemeMailto && numberOfBits(urlString.ToLower(), "mailto:") == 1)
         );
}

static int numberOfBits(string inputString, string bitToCheck)
{
    return inputString.ToLower().Split(new string[] { bitToCheck.ToLower() }, StringSplitOptions.None).Length - 1;
}
澄清

唯一能完全确定给定url是否有效的方法是实际测试它;但OP说没有连接,我理解为纯粹的字符串分析:这正是这个答案的意义所在。无论如何,正如通过评论所解释的,这篇文章的目的只是展示通过:.NET+自定义算法的方法(通过理解依靠字符串分析来实现总体适用性是相当困难的);我的建议解释了OP解释的具体问题(重复的“标题部分”)它根本不能被理解为一个普遍适用的、盲目可用的方法;而是一个带有示例功能的通用框架(仅仅是概念证明)

澄清2


如以下评论中与Jon Hanna的对话所示,我不知道还有第三种选择:分析未来IP地址(即,数字已经放在一起,但IP地址可用性尚未检查,因此未开始确定IP地址生成);通过查看,还可以确定给定字符串成为有效URL地址的可能性(在预期条件下)在任何情况下,这也不能被认为是一个100%可靠的过程,因为所分析的IP地址不是确定的。在任何情况下,Jon Hanna都比我更适合谈论这个替代方案的局限性。

它不是一个无效的URI,甚至不是一个永远不会工作的URI:你可以在bro中使用它wser是一个本地机器名为“http”的地方(或者如果您将主机文件设置为调用该机器)

问题是完全正确的URI
http://http://www.Google.com
,通常以
http://http//www.Google.com
,因为除非包含端口号,否则通常不在主机后面包含
,因为它找不到名为“http”的机器,所以不起作用

现在,即使这有时会起作用,当然也不会一直起作用。因此,这与URI的问题不同http://www.thisdoesnotexistbecauseijustmdeitup.com/

如果您还需要检测该案例,那么除了连接到Internet之外,真的没有其他方法

如果您需要检测将在全球范围内工作的URI,而不仅仅是在特定的LAN上,那么:

static bool IsGloballyUsableWebMailorFtpUrl(string urlString)
{
  Uri uri;
  if(!Uri.TryCreate(urlString, UriKind.Absolute, out uri))
    return false;
  if(uri.Scheme != Uri.UriSchemeHttp
     && uri.Scheme != Uri.UriSchemeHttps
     && uri.Scheme != Uri.UriSchemeFtp
     && uri.Scheme != Uri.UriSchemeMailto)
     return false;
  string host = uri.Host;
  IPAddress ip;
  if(!IPAddress.TryParse(host, out ip))//if we don't have an IP address in the host part.
    return host.Contains('.') && !host.EndsWith(".local", StringComparison.OrdinalIgnoreCase); // Does the domain have at least one period
                                                   // And not the "local" binding used on many
                                                   // Private networks
  var octets = ip.GetAddressBytes();
  if(octets.Length == 4)
    switch(octets[0])//We've an IPv4 IP address, check it's not reserved.
    {
      case 0: case 10: case 127:
        return false;
      case 128: case 191:
        return octets[1] != 0;
      case 169:
        return octets[1] != 254;
      case 172:
        return octets[1] < 16 || octets[1] > 31;
      case 192:
        return octets[1] != 168 && (octets[1] != 0 || octets[2] != 0);
      case 223:
        return octets[1] != 255 && octets[2] != 255;
      default:
        return true;
    }
  else
    {  //We've an IPv6 IP address, check it's not reserved.
      if(IPAddress.HostToNetworkOrder(1) != 1)
        octets = octets.Reverse().ToArray();
      var ipInt = new BigInteger(octets);
      //Not the neatest approach, but serves
      if(ipInt < 0)
        return true;
      if(ipInt < 2)
        return false;
      if(ipInt < 281470681743360)
        return true;
      if(ipInt < 281474976710656)
        return false;
      if(ipInt < BigInteger.Parse("524413980667603649783483181312245760"))
        return true;
      if(ipInt < BigInteger.Parse("524413980667603649783483185607213056"))
        return false;
      if(ipInt < BigInteger.Parse("42540488161975842760550356425300246528"))
        return true;
      if(ipInt < BigInteger.Parse("42540488241204005274814694018844196864"))
        return false;
      if(ipInt < BigInteger.Parse("42540489429626442988779757922003451904"))
        return true;
      if(ipInt < BigInteger.Parse("42540490697277043217009159418706657280"))
        return false;
      if(ipInt < BigInteger.Parse("42540766411282592856903984951653826560"))
        return true;
      if(ipInt < BigInteger.Parse("42540766490510755371168322545197776896"))
        return false;
      if(ipInt < BigInteger.Parse("42545680458834377588178886921629466624"))
        return true;
      if(ipInt < BigInteger.Parse("42550872755692912415807417417958686720"))
        return false;
      if(ipInt < BigInteger.Parse("334965454937798799971759379190646833152"))
        return true;
      if(ipInt < BigInteger.Parse("337623910929368631717566993311207522304"))
        return false;
      if(ipInt < BigInteger.Parse("338288524927261089654018896841347694592"))
        return true;
      if(ipInt < BigInteger.Parse("338620831926207318622244848606417780736"))
        return false;
      if(ipInt < BigInteger.Parse("338953138925153547590470800371487866880"))
        return true;
      if(ipInt < BigInteger.Parse("340282366920938463463374607431768211456"))
        return false;
      return true;
    }
}
static bool IsGloballyUsableWebMailorFtpUrl(字符串urlString)
{
Uri;
if(!Uri.TryCreate(urlString,UriKind.Absolute,out-Uri))
返回false;
if(uri.Scheme!=uri.UriSchemeHttp
&&uri.Scheme!=uri.UriSchemeHttps
&&uri.Scheme!=uri.UriSchemeFtp
&&uri.Scheme!=uri.urischemeEmailTo)
返回false;
字符串host=uri.host;
ip地址ip;
if(!IPAddress.TryParse(主机,输出ip))//如果主机部分中没有ip地址。
返回host.Contains('.')&&&!host.EndsWith(“.local”,StringComparison.OrdinalIgnoreCase);//域是否至少有一个句点
//而不是许多服务器上使用的“本地”绑定
//专用网络
var octets=ip.GetAddressBytes();
如果(八位字节长度==4)
开关(八位字节[0])//我们有一个IPv4 IP地址,请检查它是否未保留。
{
案例0:案例10:案例127:
返回false;
案例128:案例191:
返回八位字节[1]!=0;
案例169:
返回八位字节[1]!=254;
案例172:
返回八位字节[1]<16 | |八位字节[1]>31;
案例192:
返回八位字节[1]!=168&(八位字节[1]!=0 | |八位字节[2]!=0);
案例223:
返回八位字节[1]!=255和八位字节[2]!=255;
违约:
返回true;
}
其他的
{//我们有一个IPv6 IP地址,请检查它是否未保留。
if(IP地址.主机网络订单(1)!=1)
八位字节=八位字节。反转().ToArray();
var ipInt=新的大整数(八位字节);
//这不是最整洁的方法,但很有用
if(ipInt<0)
返回true;
if(ipInt<2)
返回false;
如果(ipInt<281470681743360)
返回true;
如果(ipInt<281474976710656)
返回false;
if(ipInt