Refine Uri Host property documentation: clarify IdnHost behavior and focus on Host/IdnHost#12301
Refine Uri Host property documentation: clarify IdnHost behavior and focus on Host/IdnHost#12301
Conversation
Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates the API reference documentation for System.Uri host-related properties to better describe real-world behavior (especially around IDN/punycode and IPv6 zone IDs) and adds a new C# snippet to compare host outputs across URI types.
Changes:
- Refines remarks for
Uri.Host,Uri.IdnHost, andUri.DnsSafeHost, including new comparison sections focused onHostvsIdnHost. - Adds a new
HostComparisonC# snippet (and project) demonstrating host outputs for DNS names, IDNs, IPv4, and IPv6 (with and without zone IDs). - Updates some wording in existing remarks/examples to be more direct and consistent in tone.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| xml/System/Uri.xml | Updates remarks/comparisons for Host, IdnHost, and DnsSafeHost, and wires in the new host comparison snippet. |
| snippets/csharp/System/Uri/HostComparison/source.cs | New snippet demonstrating differences between Host, IdnHost, and DnsSafeHost across host types. |
| snippets/csharp/System/Uri/HostComparison/Project.csproj | New snippet project to compile the HostComparison example. |
Comments suppressed due to low confidence (1)
xml/System/Uri.xml:1620
- The PR description says the F# and VB examples were removed, but this file still references the F# and VB snippet sources for the DnsSafeHost example. Either update the description or remove these references (and the corresponding snippet files) to keep the change consistent.
The following example creates a <xref:System.Uri> instance from a string. It illustrates the difference between the value returned from <xref:System.Uri.Host%2A>, which returns the host name or address specified in the URI, and the value returned from <xref:System.Uri.DnsSafeHost%2A>, 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":::
:::code language="vb" source="~/snippets/visualbasic/System/Uri/.ctor/nclurienhancements.vb" id="Snippet4":::
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| </PropertyGroup> |
There was a problem hiding this comment.
Other Uri C# snippet projects in this directory target net6.0. This new snippet project targets net8.0, which is inconsistent and can make snippet compilation requirements vary across the Uri docs set. Consider targeting net6.0 here as well unless there's a specific net8.0 requirement.
|
|
||
| The <xref:System.Uri.DnsSafeHost%2A> property is a legacy property that depends on configuration settings. Use <xref:System.Uri.IdnHost%2A> instead for consistent, configuration-independent behavior. | ||
|
|
||
| The <xref:System.Uri.DnsSafeHost%2A> property is dependent on configuration settings in .NET Framework apps, as discussed later in this topic. The <xref:System.Uri.IdnHost%2A> property is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because <xref:System.Uri.IdnHost%2A> is guaranteed to always be DNS safe. |
There was a problem hiding this comment.
The remarks introduce that IdnHost can return non-ASCII for invalid or malformed hostnames, but later this section still claims IdnHost is "guaranteed to always be DNS safe." That guarantee is inconsistent with the behavior described above and should be softened or removed to avoid overpromising.
| The <xref:System.Uri.DnsSafeHost%2A> property is dependent on configuration settings in .NET Framework apps, as discussed later in this topic. The <xref:System.Uri.IdnHost%2A> property is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because <xref:System.Uri.IdnHost%2A> is guaranteed to always be DNS safe. | |
| The <xref:System.Uri.DnsSafeHost%2A> property is dependent on configuration settings in .NET Framework apps, as discussed later in this topic. The <xref:System.Uri.IdnHost%2A> property is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A>, because <xref:System.Uri.IdnHost%2A> typically returns a value that's suitable for DNS resolution. |
| The deprecated <xref:System.Uri.DnsSafeHost%2A> property is dependent on *app.config* settings, which can't be changed by Windows Store applications. <xref:System.Uri.IdnHost%2A> is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because <xref:System.Uri.IdnHost%2A> is guaranteed to always be DNS safe, no matter what the current *app.config* settings might be. | ||
|
|
||
| ## Escaping behavior |
There was a problem hiding this comment.
This paragraph calls DnsSafeHost "deprecated", but the API isn't marked obsolete in this file (no Obsolete attribute/obsolete metadata). Consider rephrasing to "legacy"/"historical" (as used earlier in this doc) unless the API is actually deprecated/obsolete.
| The deprecated <xref:System.Uri.DnsSafeHost%2A> property is dependent on *app.config* settings, which can't be changed by Windows Store applications. <xref:System.Uri.IdnHost%2A> is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because <xref:System.Uri.IdnHost%2A> is guaranteed to always be DNS safe, no matter what the current *app.config* settings might be. | |
| ## Escaping behavior | |
| The legacy <xref:System.Uri.DnsSafeHost%2A> property is dependent on *app.config* settings, which can't be changed by Windows Store applications. <xref:System.Uri.IdnHost%2A> is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because <xref:System.Uri.IdnHost%2A> is guaranteed to always be DNS safe, no matter what the current *app.config* settings might be. | |
| ## Escaping behavior |
| - Use <xref:System.Uri.Host%2A> when you need the original host string as it appears in the URI (for display or comparison). | ||
| - Use <xref:System.Uri.IdnHost%2A> when you need a format suitable for DNS resolution or network APIs. | ||
|
|
||
| The deprecated <xref:System.Uri.DnsSafeHost%2A> property is dependent on *app.config* settings, which can't be changed by Windows Store applications. <xref:System.Uri.IdnHost%2A> is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because <xref:System.Uri.IdnHost%2A> is guaranteed to always be DNS safe, no matter what the current *app.config* settings might be. |
There was a problem hiding this comment.
This sentence says IdnHost is "guaranteed to always be DNS safe", but earlier in this section you note that invalid or malformed hostnames might return non-ASCII values, and IPv6 results can include a zone ID. Please remove or qualify the guarantee so it matches the behavior you describe.
| The deprecated <xref:System.Uri.DnsSafeHost%2A> property is dependent on *app.config* settings, which can't be changed by Windows Store applications. <xref:System.Uri.IdnHost%2A> is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because <xref:System.Uri.IdnHost%2A> is guaranteed to always be DNS safe, no matter what the current *app.config* settings might be. | |
| The deprecated <xref:System.Uri.DnsSafeHost%2A> property is dependent on *app.config* settings, which can't be changed by Windows Store applications. <xref:System.Uri.IdnHost%2A> is provided as the preferred alternative to using <xref:System.Uri.DnsSafeHost%2A> because it doesn't depend on *app.config* settings, and it's designed to produce a host value that works for typical DNS resolution scenarios. Callers should still validate or normalize the returned value, especially for malformed hostnames or IPv6 addresses that include a 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) |
There was a problem hiding this comment.
This IPv6 zone ID example uses http://[fe80::1%10].... In URI syntax, the % that introduces the zone ID needs to be percent-encoded (%25) inside the URI literal (as shown elsewhere in the docs with %254). As written, %10 is a percent-escape sequence and won't represent a zone ID of 10 reliably. Update the input URI (and the expected output comments) to use the correctly escaped form.
| 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) | |
| Uri uri4 = new Uri("http://[fe80::1%2510]:8080/path"); | |
| Console.WriteLine($" Host: {uri4.Host}"); // fe80::1%10 (with zone ID 10) | |
| Console.WriteLine($" IdnHost: {uri4.IdnHost}"); // fe80::1%10 (with zone ID 10) | |
| Console.WriteLine($" DnsSafeHost: {uri4.DnsSafeHost}"); // fe80::1%10 (with zone ID 10) |
Documentation for
Uri.Host,Uri.IdnHost, andUri.DnsSafeHostneeded refinement to avoid overpromising IdnHost behavior and to steer users toward the two primary properties.Changes
Clarified IdnHost punycode encoding: Added qualification that punycode applies to "valid international domain names" with explicit note that invalid/malformed hostnames might return non-ASCII values
Refocused property comparisons: Changed from three-property comparisons to Host vs IdnHost comparisons, positioning DnsSafeHost as a legacy property dependent on configuration
Simplified code examples: Kept only C# snippets, removed F# and VB versions
Fixed DnsSafeHost example comment: Updated from "depends on configuration" to actual value
münchen.deExample
Updated documentation now states:
Comparison sections now guide users to choose between:
Host: Original host string as it appears in the URI (for display/comparison)IdnHost: Format suitable for DNS resolution (punycode for valid IDNs, zone IDs for IPv6)Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.