diff --git a/snippets/csharp/System/Uri/HostComparison/Project.csproj b/snippets/csharp/System/Uri/HostComparison/Project.csproj
new file mode 100644
index 00000000000..dd4b56868ac
--- /dev/null
+++ b/snippets/csharp/System/Uri/HostComparison/Project.csproj
@@ -0,0 +1,6 @@
+
+
+ Exe
+ net8.0
+
+
diff --git a/snippets/csharp/System/Uri/HostComparison/source.cs b/snippets/csharp/System/Uri/HostComparison/source.cs
new file mode 100644
index 00000000000..38be1206f6b
--- /dev/null
+++ b/snippets/csharp/System/Uri/HostComparison/source.cs
@@ -0,0 +1,50 @@
+using System;
+
+public class UriHostComparison
+{
+ public static void Main()
+ {
+ //
+ // Demonstrate differences between Host, IdnHost, and DnsSafeHost.
+
+ // Example 1: Regular hostname (ASCII).
+ Console.WriteLine("Example 1: Regular ASCII hostname");
+ Uri uri1 = new Uri("http://www.contoso.com:8080/path");
+ Console.WriteLine($" Host: {uri1.Host}"); // www.contoso.com
+ Console.WriteLine($" IdnHost: {uri1.IdnHost}"); // www.contoso.com
+ Console.WriteLine($" DnsSafeHost: {uri1.DnsSafeHost}"); // www.contoso.com
+ Console.WriteLine();
+
+ // Example 2: International domain name (non-ASCII).
+ Console.WriteLine("Example 2: International domain name");
+ Uri uri2 = new Uri("http://münchen.de/path");
+ Console.WriteLine($" Host: {uri2.Host}"); // münchen.de (original)
+ Console.WriteLine($" IdnHost: {uri2.IdnHost}"); // xn--mnchen-3ya.de (punycode)
+ Console.WriteLine($" DnsSafeHost: {uri2.DnsSafeHost}"); // münchen.de
+ Console.WriteLine();
+
+ // Example 3: IPv6 address without zone ID.
+ Console.WriteLine("Example 3: IPv6 address without zone ID");
+ Uri uri3 = new Uri("http://[::1]:8080/path");
+ Console.WriteLine($" Host: {uri3.Host}"); // [::1] (with brackets)
+ Console.WriteLine($" IdnHost: {uri3.IdnHost}"); // ::1 (without brackets)
+ Console.WriteLine($" DnsSafeHost: {uri3.DnsSafeHost}"); // ::1 (without brackets)
+ Console.WriteLine();
+
+ // Example 4: IPv6 link-local address with zone ID.
+ Console.WriteLine("Example 4: IPv6 link-local address with zone ID");
+ Uri uri4 = new Uri("http://[fe80::1%10]:8080/path");
+ Console.WriteLine($" Host: {uri4.Host}"); // [fe80::1] (with brackets, no zone ID)
+ Console.WriteLine($" IdnHost: {uri4.IdnHost}"); // fe80::1%10 (without brackets, with zone ID)
+ Console.WriteLine($" DnsSafeHost: {uri4.DnsSafeHost}"); // fe80::1%10 (without brackets, with zone ID)
+ Console.WriteLine();
+
+ // Example 5: IPv4 address.
+ Console.WriteLine("Example 5: IPv4 address");
+ Uri uri5 = new Uri("http://192.168.1.1:8080/path");
+ Console.WriteLine($" Host: {uri5.Host}"); // 192.168.1.1
+ Console.WriteLine($" IdnHost: {uri5.IdnHost}"); // 192.168.1.1
+ Console.WriteLine($" DnsSafeHost: {uri5.DnsSafeHost}"); // 192.168.1.1
+ //
+ }
+}
diff --git a/xml/System/Uri.xml b/xml/System/Uri.xml
index a23c410227e..adb73c3221e 100644
--- a/xml/System/Uri.xml
+++ b/xml/System/Uri.xml
@@ -1553,16 +1553,25 @@ The URI formed by combining and property is set, if one was specified when this instance was constructed.
-If you used an escaped string to construct this instance (for example, `"http://[fe80::200:39ff:fe36:1a2d%254]/temp/example.htm"`), then DnsSafeHost returns an escaped string. Unescape any escaped string returned from `DnsSafeHost` before using that string for DNS resolution (see the Example). If you used an invalid unescaped string to construct this instance (for example, "http://[fe80::200:39ff:fe36:1a2d%4]/temp/example.htm"), then DnsSafeHost returns an unescaped string.
+If you used an escaped string to construct this instance (for example, `"http://[fe80::200:39ff:fe36:1a2d%254]/temp/example.htm"`), then returns an escaped string. Unescape any escaped string returned from `DnsSafeHost` before using that string for DNS resolution (see the Example). If you used an invalid unescaped string to construct this instance (for example, "http://[fe80::200:39ff:fe36:1a2d%4]/temp/example.htm"), then returns an unescaped string.
- The property is dependent on configuration settings in .NET Framework apps, as discussed later in this topic. The property is provided as the preferred alternative to using , because is guaranteed to always be DNS safe.
+## Comparison with other Host properties
+
+ The class provides two main host properties:
+
+ - : Returns the host as it appears in the URI. For IPv6, includes brackets but not the zone ID.
+ - : Returns a format suitable for DNS resolution. For valid international domain names, applies punycode encoding. For IPv6, doesn't include brackets but does include the zone ID.
+
+ The property is a legacy property that depends on configuration settings. Use instead for consistent, configuration-independent behavior.
+
+ The property is dependent on configuration settings in .NET Framework apps, as discussed later in this topic. The property is provided as the preferred alternative to using because is guaranteed to always be DNS safe.
The property was extended in .NET Framework v3.5, 3.0 SP1, and 2.0 SP1 to provide International Resource Identifier (IRI) support based on RFC 3987. However, to ensure application compatibility with prior versions, you must specifically enable it in .NET Framework apps. To enable support for IRI, the following two changes are required:
@@ -1597,14 +1606,14 @@ If you used an escaped string to construct this instance (for example, `"http://
- idn enabled = None
- This value will not convert any Unicode domain names to use Punycode. This is the default value, which is consistent with the .NET Framework 2.0 behavior.
+ This value won't convert any Unicode domain names to use Punycode. This is the default value, which is consistent with the .NET Framework 2.0 behavior.
Enabling IRI parsing (iriParsing enabled = `true`) normalizes and checks characters according to the IRI rules in RFC 3987. The default value is `false` and normalizes and checks characters according to RFC 2396 and RFC 2732 (for IPv6 literals).
For more information on IRI support, see the Remarks section for the class.
## Examples
- The following example creates a instance from a string. It illustrates the difference between the value returned from , which returns the host name or address specified in the URI, and the value returned from , which returns an address that is safe to use in DNS resolution.
+ The following example creates a instance from a string. It illustrates the difference between the value returned from , which returns the host name or address specified in the URI, and the value returned from , which returns an address that's safe to use in DNS resolution.
:::code language="csharp" source="~/snippets/csharp/System/Uri/.ctor/nclurienhancements.cs" id="Snippet4":::
:::code language="fsharp" source="~/snippets/fsharp/System/Uri/.ctor/nclurienhancements.fs" id="Snippet4":::
@@ -2605,7 +2614,24 @@ The following examples show a URI and the results of calling property, this property value does not include the port number.
+ Unlike the property, this property value doesn't include the port number.
+
+ The behavior of this property depends on the host type:
+
+ - For **regular DNS hostnames**: Returns the escaped input. Non-ASCII characters are returned as-is without punycode encoding.
+ - For **IPv6 addresses**: Returns the address with square brackets (for example, `[::1]` or `[fe80::1]`) but doesn't include the zone ID (scope) even if one was specified in the original URI.
+ - For **IPv4 addresses**: Returns the dotted-decimal notation (for example, `192.168.1.1`).
+
+## Comparison with IdnHost
+
+ The class provides two main host properties:
+
+ - : Returns the host as it appears in the URI. For IPv6, includes brackets but not the zone ID.
+ - : Returns a format suitable for DNS resolution. For valid international domain names, applies punycode encoding. For IPv6, doesn't include brackets but does include the zone ID.
+
+ Which property to use depends on your scenario:
+ - Use when you need the original host string as it appears in the URI (for display or comparison).
+ - Use when you need a format suitable for DNS resolution or network APIs.
## Examples
The following example writes the host name (`www.contoso.com`) of the server to the console.
@@ -2614,6 +2640,10 @@ The following examples show a URI and the results of calling and for various URI types:
+
+ :::code language="csharp" source="~/snippets/csharp/System/Uri/HostComparison/source.cs" id="SnippetHostComparison":::
+
]]>
This instance represents a relative URI, and this property is valid only for absolute URIs.
@@ -2718,11 +2748,36 @@ The following examples show a URI and the results of calling for the hostname.
+ This property is provided for use with lower-level networking protocols that require the domain name in Punycode form or need DNS-safe formatting.
+
+ The behavior of this property depends on the host type:
+
+ - For **regular DNS hostnames**: For valid international domain names, non-ASCII characters are punycode encoded (for example, `münchen.de` becomes `xn--mnchen-3ya.de`). Invalid or malformed hostnames might return non-ASCII values.
+ - For **IPv6 addresses**: Returns the address without square brackets but includes the zone ID (scope) if one was specified (for example, `::1` or `fe80::1%18`).
+ - For **IPv4 addresses**: Returns the dotted-decimal notation (for example, `192.168.1.1`).
+
+## Comparison with Host
+
+ The class provides two main host properties:
+
+ - : Returns the host as it appears in the URI. For IPv6, includes brackets but not the zone ID.
+ - : Returns a format suitable for DNS resolution. For valid international domain names, applies punycode encoding. For IPv6, doesn't include brackets but does include the zone ID.
+
+ Which property to use depends on your scenario:
+ - Use when you need the original host string as it appears in the URI (for display or comparison).
+ - Use when you need a format suitable for DNS resolution or network APIs.
+
+ The deprecated property is dependent on *app.config* settings, which can't be changed by Windows Store applications. is provided as the preferred alternative to using because is guaranteed to always be DNS safe, no matter what the current *app.config* settings might be.
+
+## Escaping behavior
+
+ If you used an escaped string to construct this instance (for example, `"http://[fe80::200:39ff:fe36:1a2d%254]/temp/example.htm"`), then returns an escaped string. You should unescape any escaped string returned from before using that string for DNS resolution. Be aware that if you used an invalid unescaped string to construct this instance (for example, "http://[fe80::200:39ff:fe36:1a2d%4]/temp/example.htm"), then returns an unescaped string.
+
+## Examples
- The deprecated property is dependent on *app.config* settings, which cannot be changed by Windows Store applications. IdnHost is provided as the preferred alternative to using , because is guaranteed to always be DNS safe, no matter what the current *app.config* settings might be.
+ The following example demonstrates the differences between and for various URI types:
- If you used an escaped string to construct this instance (for example, `"http://[fe80::200:39ff:fe36:1a2d%254]/temp/example.htm"`), then IdnHost returns an escaped string. You should unescape any escaped string returned from IdnHost before using that string for DNS resolution. Be aware that if you used an invalid unescaped string to construct this instance (for example, "http://[fe80::200:39ff:fe36:1a2d%4]/temp/example.htm"), then IdnHost returns an unescaped string.
+ :::code language="csharp" source="~/snippets/csharp/System/Uri/HostComparison/source.cs" id="SnippetHostComparison":::
]]>