Uri 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
提供统一资源标识符(URI)的对象表示形式,并轻松访问 URI 的各个部分。
public ref class Uri
public ref class Uri : IEquatable<Uri ^>, ISpanFormattable, System::Runtime::Serialization::ISerializable
public ref class Uri : System::Runtime::Serialization::ISerializable
public ref class Uri : ISpanFormattable, System::Runtime::Serialization::ISerializable
public ref class Uri : MarshalByRefObject, System::Runtime::Serialization::ISerializable
public class Uri
public class Uri : IEquatable<Uri>, ISpanFormattable, System.Runtime.Serialization.ISerializable
public class Uri : System.Runtime.Serialization.ISerializable
public class Uri : ISpanFormattable, System.Runtime.Serialization.ISerializable
[System.Serializable]
public class Uri : MarshalByRefObject, System.Runtime.Serialization.ISerializable
[System.Serializable]
[System.ComponentModel.TypeConverter(typeof(System.UriTypeConverter))]
public class Uri : System.Runtime.Serialization.ISerializable
type Uri = class
type Uri = class
interface IEquatable<Uri>
interface IFormattable
interface ISpanFormattable
interface ISerializable
type Uri = class
interface ISerializable
type Uri = class
interface ISpanFormattable
interface IFormattable
interface ISerializable
type Uri = class
interface IFormattable
interface ISpanFormattable
interface IEquatable<Uri>
interface ISerializable
[<System.Serializable>]
type Uri = class
inherit MarshalByRefObject
interface ISerializable
[<System.Serializable>]
[<System.ComponentModel.TypeConverter(typeof(System.UriTypeConverter))>]
type Uri = class
interface ISerializable
Public Class Uri
Public Class Uri
Implements IEquatable(Of Uri), ISerializable, ISpanFormattable
Public Class Uri
Implements ISerializable
Public Class Uri
Implements ISerializable, ISpanFormattable
Public Class Uri
Inherits MarshalByRefObject
Implements ISerializable
- 继承
-
Uri
- 继承
- 属性
- 实现
示例
以下示例创建类的 Uri 一个实例,并使用它执行 GET HttpClient请求。
Uri siteUri = new Uri("http://www.contoso.com/");
// HttpClient lifecycle management best practices:
// https://mms.heiai.top/dotnet/fundamentals/networking/http/httpclient-guidelines#recommended-use
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, siteUri);
HttpResponseMessage response = client.Send(request);
let siteUri = Uri "http://www.contoso.com/"
// HttpClient lifecycle management best practices:
// https://mms.heiai.top/dotnet/fundamentals/networking/http/httpclient-guidelines#recommended-use
use client = new HttpClient ()
use request = new HttpRequestMessage (HttpMethod.Get, siteUri)
use response = client.Send request
Dim siteUri As New Uri("http://www.contoso.com/")
' HttpClient lifecycle management best practices:
' https://mms.heiai.top/dotnet/fundamentals/networking/http/httpclient-guidelines#recommended-use
Dim client As New HttpClient()
Dim request As New HttpRequestMessage(HttpMethod.Get, siteUri)
Dim response As HttpResponseMessage = client.Send(request)
以下代码片段显示了类上各种属性的示例值。
Uri uri = new Uri("https://user:[email protected]:80/Home/Index.htm?q1=v1&q2=v2#FragmentName");
Console.WriteLine($"AbsolutePath: {uri.AbsolutePath}");
Console.WriteLine($"AbsoluteUri: {uri.AbsoluteUri}");
Console.WriteLine($"DnsSafeHost: {uri.DnsSafeHost}");
Console.WriteLine($"Fragment: {uri.Fragment}");
Console.WriteLine($"Host: {uri.Host}");
Console.WriteLine($"HostNameType: {uri.HostNameType}");
Console.WriteLine($"IdnHost: {uri.IdnHost}");
Console.WriteLine($"IsAbsoluteUri: {uri.IsAbsoluteUri}");
Console.WriteLine($"IsDefaultPort: {uri.IsDefaultPort}");
Console.WriteLine($"IsFile: {uri.IsFile}");
Console.WriteLine($"IsLoopback: {uri.IsLoopback}");
Console.WriteLine($"IsUnc: {uri.IsUnc}");
Console.WriteLine($"LocalPath: {uri.LocalPath}");
Console.WriteLine($"OriginalString: {uri.OriginalString}");
Console.WriteLine($"PathAndQuery: {uri.PathAndQuery}");
Console.WriteLine($"Port: {uri.Port}");
Console.WriteLine($"Query: {uri.Query}");
Console.WriteLine($"Scheme: {uri.Scheme}");
Console.WriteLine($"Segments: {string.Join(", ", uri.Segments)}");
Console.WriteLine($"UserEscaped: {uri.UserEscaped}");
Console.WriteLine($"UserInfo: {uri.UserInfo}");
// AbsolutePath: /Home/Index.htm
// AbsoluteUri: https://user:[email protected]:80/Home/Index.htm?q1=v1&q2=v2#FragmentName
// DnsSafeHost: www.contoso.com
// Fragment: #FragmentName
// Host: www.contoso.com
// HostNameType: Dns
// IdnHost: www.contoso.com
// IsAbsoluteUri: True
// IsDefaultPort: False
// IsFile: False
// IsLoopback: False
// IsUnc: False
// LocalPath: /Home/Index.htm
// OriginalString: https://user:[email protected]:80/Home/Index.htm?q1=v1&q2=v2#FragmentName
// PathAndQuery: /Home/Index.htm?q1=v1&q2=v2
// Port: 80
// Query: ?q1=v1&q2=v2
// Scheme: https
// Segments: /, Home/, Index.htm
// UserEscaped: False
// UserInfo: user:password
let uri = Uri "https://user:[email protected]:80/Home/Index.htm?q1=v1&q2=v2#FragmentName"
printfn $"AbsolutePath: {uri.AbsolutePath}"
printfn $"AbsoluteUri: {uri.AbsoluteUri}"
printfn $"DnsSafeHost: {uri.DnsSafeHost}"
printfn $"Fragment: {uri.Fragment}"
printfn $"Host: {uri.Host}"
printfn $"HostNameType: {uri.HostNameType}"
printfn $"IdnHost: {uri.IdnHost}"
printfn $"IsAbsoluteUri: {uri.IsAbsoluteUri}"
printfn $"IsDefaultPort: {uri.IsDefaultPort}"
printfn $"IsFile: {uri.IsFile}"
printfn $"IsLoopback: {uri.IsLoopback}"
printfn $"IsUnc: {uri.IsUnc}"
printfn $"LocalPath: {uri.LocalPath}"
printfn $"OriginalString: {uri.OriginalString}"
printfn $"PathAndQuery: {uri.PathAndQuery}"
printfn $"Port: {uri.Port}"
printfn $"Query: {uri.Query}"
printfn $"Scheme: {uri.Scheme}"
printfn $"""Segments: {String.Join(", ", uri.Segments)}"""
printfn $"UserEscaped: {uri.UserEscaped}"
printfn $"UserInfo: {uri.UserInfo}"
// AbsolutePath: /Home/Index.htm
// AbsoluteUri: https://user:[email protected]:80/Home/Index.htm?q1=v1&q2=v2#FragmentName
// DnsSafeHost: www.contoso.com
// Fragment: #FragmentName
// Host: www.contoso.com
// HostNameType: Dns
// IdnHost: www.contoso.com
// IsAbsoluteUri: True
// IsDefaultPort: False
// IsFile: False
// IsLoopback: False
// IsUnc: False
// LocalPath: /Home/Index.htm
// OriginalString: https://user:[email protected]:80/Home/Index.htm?q1=v1&q2=v2#FragmentName
// PathAndQuery: /Home/Index.htm?q1=v1&q2=v2
// Port: 80
// Query: ?q1=v1&q2=v2
// Scheme: https
// Segments: /, Home/, Index.htm
// UserEscaped: False
// UserInfo: user:password
注解
统一资源标识符(URI)是 Intranet 或 Internet 上应用程序可用的资源的紧凑表示形式。 该 Uri 类定义用于处理 URI 的属性和方法,包括分析、比较和组合。 Uri 类的属性是只读的;如果要创建可修改的对象,请使用 UriBuilder 类。
相对 URI(例如,“/new/index.htm”)必须相对于基 URI 进行扩展,以便它们是绝对 URI。 MakeRelativeUri提供此方法,以便在必要时将绝对 URI 转换为相对 URI。
如果字符串是包含方案标识符的格式化 URI,则 Uri 构造函数不会转义 URI 字符串。
这些 Uri 属性返回经过转义编码的规范数据表示形式,其中 Unicode 值大于 127 的所有字符都被替换为其十六进制等效项。 若要以规范形式放置 URI, Uri 构造函数将执行以下步骤:
- 将 URI 方案转换为小写。
- 将主机名转换为小写。
- 如果主机名是 IPv6 地址,则使用规范 IPv6 地址。 ScopeId 和其他可选 IPv6 数据已删除。
- 移除默认端口号和空端口号。
- 将不使用 file:// 方案(例如“C:\my\file”)的隐式文件路径转换为具有 file:// 方案的显式文件路径。
- 没有保留用途的转义字符(也称为百分比编码八进制数)会被解码(也称为取消转义)。 这些未保留的字符包括大写和小写字母(%41-%5A 和 %61-%7A)、小数位数(%30-%39)、连字符(%2D)、句点(%2E)、下划线(%5F)和平铺(%7E)。
- 通过压缩
/./和/../等序列,对分层 URI 的路径进行规范化处理(无论序列是否转义)。 请注意,某些方案未压缩这些序列。 - 对于分层 URI,如果主机不是以正斜杠 (/) 结尾,则会添加一条正斜杠。
- 默认情况下,URI 中的任何保留字符都会根据 RFC 2396 进行转义。 如果启用了国际资源标识符或国际域名解析,那么这种行为会发生变化,在此情况下,URI 中的保留字符会根据 RFC 3986 和 RFC 3987 进行转义。
作为某些方案的构造函数规范化的一部分,点段(/./ 和 /../)被压缩(换句话说,删除它们)。
Uri 可压缩段的方案包括 http、https、tcp、net.pipe 和 net.tcp。 对于某些其他方案,这些序列不会进行压缩。 以下代码段展示了压缩的实际效果。 如有必要,转义序列将被取消转义,然后进行压缩。
var uri = new Uri("http://myUrl/../.."); // http scheme, unescaped
OR
var uri = new Uri("http://myUrl/%2E%2E/%2E%2E"); // http scheme, escaped
OR
var uri = new Uri("ftp://myUrl/../.."); // ftp scheme, unescaped
OR
var uri = new Uri("ftp://myUrl/%2E%2E/%2E%2E"); // ftp scheme, escaped
Console.WriteLine($"AbsoluteUri: {uri.AbsoluteUri}");
Console.WriteLine($"PathAndQuery: {uri.PathAndQuery}");
执行此代码时,它将返回类似于以下文本的输出。
AbsoluteUri: http://myurl/
PathAndQuery: /
可以使用 Uri 方法将 ToString 类的内容从转义编码的 URI 引用转换为可读的 URI 引用。 请注意,在 ToString 方法的输出中,某些保留字符可能仍会被转义。 这是为了支持从返回 ToString的值中明确重建 URI。
某些 URI 包括片段标识符或查询或两者兼有。 片段标识符是数字符号(#)后面的任何文本,不包括数字符号;片段文本存储在属性中 Fragment 。 查询信息是 URI 中问号(?)后面的任何文本;查询文本存储在属性中 Query 。
注释
URI 类支持 IP 地址的使用,IPv4 协议使用四部分表示法,IPv6 协议使用冒号十六进制表示法。 请记住将 IPv6 地址括在方括号中,如 http://[::1]。
国际资源标识符支持
Web 地址通常使用 URI 表示,这些 URI 由一组非常受限的字符组成:
- 大写和小写的 ASCII 字母来自英文字母。
- 数字从 0 到 9。
- 少量其他 ASCII 符号。
URI 规范记录在 RFC 2396、RFC 2732、RFC 3986 和由 Internet 工程工作队(IETF)发布的 RFC 3987 中。
有助于使用英语以外的语言识别资源的标识符,并允许非 ASCII 字符(Unicode/ISO 10646 字符集中的字符)称为国际资源标识符(IRI)。 IETF 发布的 RFC 3987 中记录了 IRI 规范。 使用 IRIs 允许 URL 包含 Unicode 字符。 规范化和字符检查是根据 RFC 3986 和 RFC 3987 中最新的 IRI 规则完成的。
可以使用和配置设置类来控制System.Configuration.IriParsingElementSystem.Configuration.IdnElement类中的 Uri IRI 和 System.Configuration.UriSection IDN 处理。 该 System.Configuration.IriParsingElement 设置启用或禁用 Uri 类中 IRI 处理。 System.Configuration.IdnElement 设置启用或禁用 Uri 类中的 IDN 处理。
首次构造System.Configuration.IriParsingElement类时,将对System.Configuration.IdnElement和System.Uri的配置设置进行一次性读取。 之后对配置设置的更改将被忽略。
该 System.GenericUriParser 类还进行了扩展,允许创建支持 IRI 和 IDN 的可自定义分析程序。 通过将System.GenericUriParser枚举中可用值的按位组合传递给System.GenericUriParserOptions构造函数,可以指定System.GenericUriParser对象的行为。 该 GenericUriParserOptions.IriParsing 类型指示分析程序支持 RFC 3987 中为国际资源标识符(IRI)指定的分析规则。
该 GenericUriParserOptions.Idn 类型指示分析程序支持主机名的国际化域名(IDN)分析。 在 .NET (Core) 和 .NET Framework 4.5+ 中,始终使用 IDN。 在以前的版本中,配置选项确定是否使用 IDN。
隐式文件路径支持
Uri 还可用于表示本地文件系统路径。 这些路径可以在以 file:// 方案开头的 URI 中 显式 表示,并在没有 file:// 方案的 URI 中 隐式 表示。 作为具体示例,以下两个 URI 均有效,并表示相同的文件路径:
Uri uri1 = new Uri("C:/test/path/file.txt") // Implicit file path.
Uri uri2 = new Uri("file:///C:/test/path/file.txt") // Explicit file path.
这些隐式文件路径不符合 URI 规范,应尽可能避免。 在基于 Unix 的系统上使用 .NET Core 时,隐式文件路径可能会特别有问题,因为绝对隐式文件路径与相对路径 不可区分 。 如果存在此类歧义, Uri 则默认将路径解释为绝对 URI。
安全注意事项
出于安全考虑,在接受来自不受信任来源的 Uri 实例和在dontEscape中将 true 设置为 时,应用程序应保持谨慎。 可以通过调用 IsWellFormedOriginalString 方法来检查 URI 字符串是否有效。
在处理不受信任的用户输入时,在信任新创建的 Uri 实例之前确认其属性的假设。
这可以通过以下方式完成:
string userInput = ...;
Uri baseUri = new Uri("https://myWebsite/files/");
if (!Uri.TryCreate(baseUri, userInput, out Uri newUri))
{
// Fail: invalid input.
}
if (!baseUri.IsBaseOf(newUri))
{
// Fail: the Uri base has been modified - the created Uri is not rooted in the original directory.
}
此验证可用于其他情况,例如处理 UNC 路径时,只需更改 baseUri以下内容即可:
Uri baseUri = new Uri(@"\\host\share\some\directory\name\");
有关设计和安全注意事项UriUriBuilder的更多详细信息,请查看以下威胁模型文档:
性能注意事项
如果使用包含 URI 的 Web.config 文件来初始化应用程序,则如果 URI 方案标识符不标准,则需要额外的时间来处理 URI。 在这种情况下,在需要 URI 时初始化应用程序受影响的部分,而不是在启动时。
构造函数
| 名称 | 说明 |
|---|---|
| Uri(SerializationInfo, StreamingContext) |
已过时.
从类的Uri指定实例初始化类的新实例SerializationInfoStreamingContext。 |
| Uri(String, Boolean) |
已过时.
已过时.
已过时.
已过时.
使用指定的 URI 初始化类的新实例 Uri ,并显式控制字符转义。 |
| Uri(String, UriCreationOptions) |
使用指定的 URI 和其他 UriURI 初始化类的新实例UriCreationOptions。 |
| Uri(String, UriKind) |
使用指定的 URI 初始化类的新实例 Uri 。 使用此构造函数可以指定 URI 字符串是相对 URI、绝对 URI 还是不确定。 |
| Uri(String) |
使用指定的 URI 初始化类的新实例 Uri 。 |
| Uri(Uri, String, Boolean) |
已过时.
已过时.
已过时.
已过时.
根据指定的基 URI 和相对 URI 初始化类的新实例 Uri ,并显式控制字符转义。 |
| Uri(Uri, String) |
根据指定的基 URI 和相对 URI 字符串初始化类的新实例 Uri 。 |
| Uri(Uri, Uri) |
字段
| 名称 | 说明 |
|---|---|
| SchemeDelimiter |
指定将通信协议方案与 URI 的地址部分分开的字符。 此字段是只读的。 |
| UriSchemeData |
提供统一资源标识符(URI)的对象表示形式,并轻松访问 URI 的各个部分。 |
| UriSchemeFile |
指定 URI 是指向文件的指针。 此字段是只读的。 |
| UriSchemeFtp |
指定通过文件传输协议(FTP)访问 URI。 此字段是只读的。 |
| UriSchemeFtps |
指定通过文件传输协议安全(FTPS)访问 URI。 此字段是只读的。 |
| UriSchemeGopher |
指定通过 Gopher 协议访问 URI。 此字段是只读的。 |
| UriSchemeHttp |
指定通过超文本传输协议(HTTP)访问 URI。 此字段是只读的。 |
| UriSchemeHttps |
指定通过安全超文本传输协议(HTTPS)访问 URI。 此字段是只读的。 |
| UriSchemeMailto |
指定 URI 是电子邮件地址,并通过简单邮件传输协议(SMTP)进行访问。 此字段是只读的。 |
| UriSchemeNetPipe |
指定通过 Windows Communication Foundation (WCF) 使用的 NetPipe 方案访问 URI。 此字段是只读的。 |
| UriSchemeNetTcp |
指定通过 Windows Communication Foundation (WCF) 使用的 NetTcp 方案访问 URI。 此字段是只读的。 |
| UriSchemeNews |
指定 URI 是 Internet 新闻组,并通过网络新闻传输协议(NNTP)进行访问。 此字段是只读的。 |
| UriSchemeNntp |
指定 URI 是 Internet 新闻组,并通过网络新闻传输协议(NNTP)进行访问。 此字段是只读的。 |
| UriSchemeSftp |
指定通过 SSH 文件传输协议(SFTP)访问 URI。 此字段是只读的。 |
| UriSchemeSsh |
指定通过安全套接字外壳协议(SSH)访问 URI。 此字段是只读的。 |
| UriSchemeTelnet |
指定通过 Telnet 协议访问 URI。 此字段是只读的。 |
| UriSchemeWs |
指定通过 WebSocket 协议 (WS) 访问 URI。 此字段是只读的。 |
| UriSchemeWss |
指定通过 WebSocket 安全协议 (WSS) 访问 URI。 此字段是只读的。 |
属性
| 名称 | 说明 |
|---|---|
| AbsolutePath |
获取 URI 的绝对路径。 |
| AbsoluteUri |
获取绝对 URI。 |
| Authority |
获取域名系统(DNS)主机名或 IP 地址以及服务器的端口号。 |
| DnsSafeHost |
获取一个主机名,该主机名(如有必要)可以安全地用于 DNS 解析。 |
| Fragment |
获取转义 URI 片段,包括前导“#”字符(如果不是空)。 |
| Host |
获取此实例的主机组件。 |
| HostNameType |
获取 URI 中指定的主机名的类型。 |
| IdnHost |
根据需要使用 Punycode 获取主机符合 RFC 3490 的国际域名。 如有必要,此字符串在未转义后可以安全地用于 DNS 解析。 |
| IsAbsoluteUri |
获取一个值,该值指示实例是否 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 关联的用户名、密码或其他特定于用户的信息。 |
方法
运营商
| 名称 | 说明 |
|---|---|
| Equality(Uri, Uri) |
确定两个 Uri 实例是否具有相同的值。 |
| Inequality(Uri, Uri) |
确定两 Uri 个实例是否没有相同的值。 |
显式接口实现
| 名称 | 说明 |
|---|---|
| IFormattable.ToString(String, IFormatProvider) |
使用指定格式设置当前实例的值的格式。 |
| ISerializable.GetObjectData(SerializationInfo, StreamingContext) |
返回序列化当前实例所需的数据。 |
| ISpanFormattable.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider) |
尝试将当前实例的值格式化为提供的字符范围。 |
适用于
线程安全性
所有成员 Uri 都是线程安全的,可以从多个线程并发使用。