Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions snippets/csharp/System/Uri/HostComparison/Project.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
Comment thread
MihaZupan marked this conversation as resolved.

</Project>
58 changes: 58 additions & 0 deletions snippets/csharp/System/Uri/HostComparison/source.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;

public class UriHostComparison
{
public static void Main()
{
// <SnippetHostComparison>
// 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();
Comment on lines +18 to +24

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Also include an example where the input is already an encoded host (xn--mnchen-3ya.de)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Example 3 covering a URI whose host is already in punycode (xn--mnchen-3ya.de), showing that Host, IdnHost, and DnsSafeHost all return the encoded form as-is.


// Example 3: International domain name already in punycode (encoded) form.
Console.WriteLine("Example 3: Already-encoded international domain name");
Uri uri2Encoded = new Uri("http://xn--mnchen-3ya.de/path");
Console.WriteLine($" Host: {uri2Encoded.Host}"); // xn--mnchen-3ya.de (as provided)
Console.WriteLine($" IdnHost: {uri2Encoded.IdnHost}"); // xn--mnchen-3ya.de (already punycode)
Console.WriteLine($" DnsSafeHost: {uri2Encoded.DnsSafeHost}"); // xn--mnchen-3ya.de
Console.WriteLine();

// Example 4: IPv6 address without zone ID.
Console.WriteLine("Example 4: 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 5: IPv6 link-local address with zone ID.
Console.WriteLine("Example 5: 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)
Comment thread
MihaZupan marked this conversation as resolved.
Console.WriteLine();

// Example 6: IPv4 address.
Console.WriteLine("Example 6: 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
Comment thread
MihaZupan marked this conversation as resolved.
// </SnippetHostComparison>
}
}
27 changes: 26 additions & 1 deletion xml/System/Uri.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,8 @@ For `uriString`, an IPv6 address in string form must be enclosed within brackets
## Remarks
For IPv6 addresses, the brackets ([]) are removed and the <xref:System.Net.IPAddress.ScopeId> property is set, if one was specified when this instance was constructed.

<xref:System.Uri.DnsSafeHost%2A> is a legacy property whose behavior depends on configuration settings in .NET Framework apps. For new code, prefer <xref:System.Uri.IdnHost%2A>, which is configuration-independent and produces a value suitable for DNS resolution. See <xref:System.Uri.Host%2A> and <xref:System.Uri.IdnHost%2A> for guidance on choosing a host property.

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.

## Examples
Expand Down Expand Up @@ -2638,13 +2640,25 @@ The following examples show a URI and the results of calling <xref:System.Uri.Ge
## Remarks
Unlike the <xref:System.Uri.Authority> property, this property value does not include the port number.

The value returned by this property depends on the host type:

- For **DNS host names** (including international domain names): Returns the escaped input. Non-ASCII characters are returned as-is and aren't punycode encoded.
- For **IPv6 addresses**: Returns the address enclosed in square brackets (for example, `[::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`).

For DNS resolution or other lower-level networking scenarios, use <xref:System.Uri.IdnHost%2A> instead, which returns a punycode-encoded form for valid international domain names and includes the zone ID (without brackets) for IPv6 addresses. Use <xref:System.Uri.Host%2A> when you want the host as it appears in the URI (for example, for display or comparison).

## Examples
The following example writes the host name (`www.contoso.com`) of the server to the console.

:::code language="csharp" source="~/snippets/csharp/System/Uri/Host/source.cs" id="Snippet1":::
:::code language="fsharp" source="~/snippets/fsharp/System/Uri/Host/source.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/System/Uri/Host/source.vb" id="Snippet1":::

The following example shows how <xref:System.Uri.Host%2A> and <xref:System.Uri.IdnHost%2A> differ across DNS, IDN, IPv4, and IPv6 inputs:

:::code language="csharp" source="~/snippets/csharp/System/Uri/HostComparison/source.cs" id="SnippetHostComparison":::

]]></format>
</remarks>
<exception cref="T:System.InvalidOperationException">This instance represents a relative URI, and this property is valid only for absolute URIs.</exception>
Expand Down Expand Up @@ -2749,10 +2763,21 @@ The following examples show a URI and the results of calling <xref:System.Uri.Ge
## Remarks
This property is provided for the use of lower-level networking protocols that require the domain name in Punycode form. If your code does not require that specific format, use <xref:System.Uri.Host*> for the hostname.

IdnHost is provided as the preferred alternative to using the deprecated <xref:System.Uri.DnsSafeHost> property, because <xref:System.Uri.IdnHost*> is guaranteed to always be DNS safe.
The value returned by this property depends on the host type:

- For **DNS host names**: For valid international domain names, non-ASCII characters are punycode encoded (for example, `münchen.de` becomes `xn--mnchen-3ya.de`). Hostnames that aren't valid IDNs might be returned as-is and include non-ASCII characters.
- For **IPv6 addresses**: Returns the address without the surrounding brackets, and 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`).

<xref:System.Uri.IdnHost%2A> is the preferred alternative to the legacy <xref:System.Uri.DnsSafeHost%2A> property, because its behavior doesn't depend on *app.config* settings and it's designed to produce a value suitable for DNS resolution. Note that for IPv6 results that include a zone ID, callers may still need to strip the zone ID before passing the value to APIs that don't accept it.

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.

## Examples
The following example shows how <xref:System.Uri.Host%2A> and <xref:System.Uri.IdnHost%2A> differ across DNS, IDN, IPv4, and IPv6 inputs:

:::code language="csharp" source="~/snippets/csharp/System/Uri/HostComparison/source.cs" id="SnippetHostComparison":::

]]></format>
</remarks>
<exception cref="T:System.InvalidOperationException">This instance represents a relative URI, and this property is valid only for absolute URIs.</exception>
Expand Down