C# System.Uri类_获取Url的各种属性_文件名_参数_域名_端口等等

作者: 来源: 日期:2021-8-5

本想写一篇类似本文的文章,但是发现网上已经有了,而且与我已经写了的部分内容是匹配的,而且原作者也测试得比较详细,所以干脆转载之,原文请见:C# System.Uri类_获取Url的各种属性_文件名_参数_域名_端口等等

以下是原文:

System.Uri 类用于处理 Uri 地址信息,常用到它的地方有,相对 Uri 地址转绝对 Uri 地址,获取 Uri 的某部分信息等等,可以说是一个非常有用的类。

一、属性

  • AbsolutePath   获取 URI 的绝对路径。 

  • AbsoluteUri     获取绝对 URI。 

  • Authority      获取服务器的域名系统 (DNS) 主机名或 IP 地址和端口号。 

  • DnsSafeHost   获得可安全用于 DNS 解析的未转义主机名。 

  • Fragment     获取转义 URI 片段。 

  • Host        获取此实例的主机部分。 

  • HostNameType  获取 URI 中指定的主机名的类型。 

  • IsAbsoluteUri   获取一个值,该值指示 Uri 实例是否为绝对 URI。 

  • IsDefaultPort   获取一个值,该值指示 URI 的端口值是否为此方案的默认值。 

  • IsFile       获取一个值,该值指示指定的 Uri 是否为文件 URI。 

  • IsLoopback     获取一个值,该值指示指定的 Uri 是否引用了本地主机。 

  • IsUnc       获取一个值,该值指示指定的 Uri 是否为统一命名约定

  • (UNC) 路径。 

  • LocalPath     获取文件名的本地操作系统表示形式。 

  • OriginalString   获取传递给 Uri 构造函数的原始 URI 字符串。 

  • PathAndQuery   获取用问号 (?) 分隔的 AbsolutePath 和 Query 属性。 

  • Port         获取此 URI 的端口号。 

  • Query       获取指定 URI 中包括的任何查询信息。 

  • Scheme      获取此 URI 的方案名称。 

  • Segments     获取包含构成指定 URI 的路径段的数组。 

  • UserEscaped     指示 URI 字符串在创建 Uri 实例之前已被完全转义。 

  • UserInfo       获取用户名、密码或其他与指定 URI 关联的特定于用户的信息。

class Program
    {
        static void Main(string[] args)
        {
            Uri uri = new Uri("http://www.baidu.com:80/2013/123.html?id=1");
            
            Console.WriteLine(uri.AbsolutePath);    // 输出 /2013/123.html
            Console.WriteLine(uri.AbsoluteUri);     // 输出 http://www.baidu.com/2013/123.html?id=1
            Console.WriteLine(uri.Authority);       // 输出 www.baidu.com。本网注:如果端口不是 80,则输出形如:www.baidu.com:81 
            Console.WriteLine(uri.DnsSafeHost);     // 输出 www.baidu.com
            Console.WriteLine(uri.Fragment);        // 输出 
            Console.WriteLine(uri.Host);            // 输出 www.baidu.com
            Console.WriteLine(uri.IsAbsoluteUri);   // 输出 True
            Console.WriteLine(uri.IsDefaultPort);   // 输出 True
            Console.WriteLine(uri.IsFile);          // 输出 False

            Uri uri1 = new Uri(@"D:\test\test.txt");
            Console.WriteLine(uri1.IsFile);          // 输出 True

            Console.WriteLine(uri.IsLoopback);      // 输出 False
            Console.WriteLine(uri1.IsLoopback);     // 输出 True

            Console.WriteLine(uri.IsUnc);           // 输出 False
            Console.WriteLine(uri.LocalPath);       // 输出 /2013/123.html
            Console.WriteLine(uri.OriginalString);  // 输出 http://www.baidu.com:80/2013/123.html
            Console.WriteLine(uri.PathAndQuery);    // 输出 /2013/123.html?id=1
            Console.WriteLine(uri.Port);            // 输出 80
            Console.WriteLine(uri.Query);           // 输出 ?id=1
            Console.WriteLine(uri.Scheme);          // 输出 http
            string[] strArr = uri.Segments;
            foreach (string str in strArr)
            {
                Console.WriteLine(str);     // 输出 /   2013/      123.html
            }

            Console.WriteLine(uri.UserEscaped);     // 输出 False;
            Console.WriteLine(uri.UserInfo);        // 输出 

            Console.ReadKey();
        }
    }

【本网注开始】

也就是说完整网址等于:[Scheme]://[Authority][PathAndQuery]

如果网址访问时忽略了默认页,即这样来访问:http://localhost:123/?param=1

那么得到的 PathAndQuery 是:/default.aspx?param=1,也就是说自动把 default.aspx 带上了的。

可以看出 default.aspx 是小写的(我们真实名字是 Default.aspx)

那如果我们在浏览器中指定 DEFAULT.aspx 这样大写来访问,结果怎样呢?结果是遵照浏览器指定的,包括 LocalPath 属性也是。

还有一些映射的问题,更麻烦了,就可以参照:ASP.NET 中 Request 各种 Path、Url 区别 - ITPOW (itpow.com)

【本网注完】

二、方法

  • CheckHostName     确定指定的主机名是否为有效的 DNS 名称。 

  • CheckSchemeName    确定指定的方案名是否有效。 

  • Compare          使用指定的比较规则比较两个 URI 的指定部分。 

  • EscapeDataString    将字符串转换为它的转义表示形式。 

  • EscapeUriString     将 URI 字符串转换为它的转义表示形式。 

  • FromHex          获取十六进制数字的十进制值。 

  • GetComponents     使用特殊字符的指定转义,获取当前实例的指定部分。 

  • GetLeftPart        获取 Uri 实例的指定部分。 

  • GetObjectData       返回序列化当前实例所需的数据。 

  • HexEscape         将指定的字符转换它的等效十六进制字符。 

  • HexUnescape       将字符的指定十六进制表示形式转换为字符。 

  • IsBaseOf         确定当前的 Uri 实例是否为指定 Uri 实例的基。 

  • IsHexDigit        确定指定的字符是否为有效的十六进制数字。 

  • IsHexEncoding       确定字符串中的一个字符是否为十六进制编码。 

  • IsWellFormedOriginalString   指示用于构造此 Uri 的字符串是否格式良好,以及它是否不需要进一步转义。 

  • IsWellFormedUriString   通过尝试用字符串构造一个 URI 来指示字符串是否为格式良好的,并确保字符串不需要进一步转义。 

  • MakeRelativeUri      确定两个 Uri 实例之间的差异。 

  • TryCreate         已重载。 创建一个新的 Uri。在无法创建 Uri 时不引发异常。 

  • UnescapeDataString   将字符串转换为它的非转义表示形式。

class Program
    {
        static void Main(string[] args)
        {
        

            Uri uri = new Uri("http://www.baidu.com:80/2013/123.html?id=1");
            UriHostNameType unt = Uri.CheckHostName("http://www.baidu.com");
            Console.WriteLine(unt.ToString());   //输出Unknown    UriHostNameType 是一个枚举,定义主机名类型

            Console.WriteLine(Uri.CheckSchemeName("http://www.baidu.com")); //输出 False
            Console.WriteLine(Uri.CheckSchemeName("http"));     //输出 True
            Console.WriteLine(Uri.CheckSchemeName("https"));    //输出 True
            //Uri uri1 = new Uri("http://www.baidu.com");
            //Uri.Compare(uri,uri1);

            //Uri.EscapeDataString对冒号(:)、斜杠(/)、空格、中文、井号(#)都进行了编码,可对参数编码
            Console.WriteLine(Uri.EscapeDataString("http://www.baidu.com:80/2013/123.html?id=1"));  //输出 http%3A%2F%2Fwww.baidu.com%3A80%2F2013%2F123.html%3Fid%3D1     Uri转义
            //Uri.EscapeUriString对空格进行了编码,也对中文进行了编码,但对冒号(:)、斜杠(/)和井号(#)未编码,所以此方法可以用于网址进行编码,但不能对参数进行编码
            //Uri.EscapeUriString对URI的网址部分编码,用Uri.EscapeDataString对URI中传递的参数进行编码。 
            Console.WriteLine(Uri.EscapeUriString("http://www.baidu.com:80/2013/123.html?id=1&你好"));//输出 http://www.baidu.com:80/2013/123.html?id=1&%E4%BD%A0%E5%A5%BD
            
            string str = "http%3A%2F%2Fwww.baidu.com%3A80%2F2013%2F123.html%3Fid%3D1";
            Console.WriteLine(Uri.UnescapeDataString(str)); //输出 http://www.baidu.com:80/2013/123.html?id=1 , 将Url还原成不转义的形式

            Console.WriteLine(Uri.FromHex('A'));    //输出 10  获取16进制数字的十进制值
            Console.WriteLine(Uri.HexEscape('2'));  //输出 %32 转换它的等效十六进制字符。 
            Console.WriteLine(Uri.IsHexDigit('F'));  //输出True 确定指定的字符是否为有效的十六进制数字。 

            int index = 0;
            if (Uri.IsHexEncoding("%75", index))
                Console.WriteLine("该编码代表的字符是 :{0}", Uri.HexUnescape("%75", ref index));
            else
                Console.WriteLine("这不是16禁止编码");

            //以下两个实例方法GetLeftPart与GetComponents都用于获取Uri中的一部分,可以是端口,方案,参数等等。
            Console.WriteLine(uri.GetComponents(UriComponents.Scheme,UriFormat.Unescaped)); //输出 http   获取Uri中的一部分,两个参数都是枚举
            Console.WriteLine(uri.GetLeftPart(UriPartial.Scheme));  //输出 http://

            Uri uri1 = new Uri("Http://www.baidu.com");
            Console.WriteLine(uri.IsBaseOf(uri1));  //输出 False
            Console.WriteLine(uri1.IsBaseOf(uri));  //输出 True

            //TryCreate也可用于相对路径转绝对路径,返回一个新的uri并且不成功时不报异常
            Uri uri2 = new Uri("http://www.baidu.com/a/b/c.html");
            Uri uri3;
            Uri.TryCreate(uri2,"../123.html",out uri3);
            Console.WriteLine(uri3);    //输出 http://www.baidu.com/a/123.html

            Uri uri4 = uri2.MakeRelativeUri(uri3);
            Console.WriteLine(uri4);    //输出..123/html
            //再来一个

            Uri uri5 = new Uri("http://www.baidu.com/a/b/d.html");
            Uri uri6 = new Uri("http://www.baidu.com/a/b/c.html");

            Uri uri7 = uri5.MakeRelativeUri(uri6);
            Console.WriteLine(uri7);    //输出 c.html //这样就表示目录相同,文件名不同,相对于第一个调用Uri来说的

            //确定文件是否不需要转义,没特殊字符就不需要转移
            //以下两个方法基本一致,只是一个是静态方法,一个是实例方法而已
            Console.WriteLine(Uri.IsWellFormedUriString("http://www.baidu.com", UriKind.Absolute));             //输出 True UriKind是一个枚举
            Console.WriteLine(Uri.IsWellFormedUriString("http://www.baidu.com/123.html?名字=张三", UriKind.Absolute));    //输出 False    表示需要转义
            
            Console.WriteLine(uri.IsWellFormedOriginalString());   //True 此 Uri 的字符串是否格式良好,以及它是否不需要进一步转义。 
            Uri uri8 = new Uri("http://www.baidu.com/123.html?名字=张三");
            Console.WriteLine(uri8.IsWellFormedOriginalString());   //输出False 
            Console.ReadKey();
        }
    }

有时间要看好点,这个类还是很有用的。

另附上一个常用的功能,相对Uri转绝对Uri,这是是利用构造函数实现的,传入一个baseUri就能够实现,如下代码:

static void Main(string[] args)
        {
            Uri uri = new Uri("http://www.jmeii.com/a/b/index.html");
            Uri uri2 = new Uri(uri,"../123.html");
            Console.WriteLine(uri2.ToString());     //输出http://www.jmeii.com/a/123.html

            Console.ReadKey();
        }
相关文章