Document Uri.Query and Uri.Fragment include leading delimiters #12002
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uri.QueryandUri.Fragmentinclude the leading?and#delimiters respectively, which differs from RFC 3986's definition where query and fragment components exclude these delimiters. This behavior has existed since .NET Framework 1.1 and cannot change without breaking existing code.Changes
#delimiter is included, whereas RFC 3986 defines fragment without the delimiter?delimiter is included, whereas RFC 3986 defines query without the delimiterContext
This documentation enhancement helps developers understand the behavior when working with URIs, particularly when integrating with systems that follow RFC 3986 strictly.
Original prompt
This section details on the original issue you should resolve
<issue_title>Uri.Query should not start with a question mark</issue_title>
<issue_description>### Description
Currently, the
Queryproperty of aUristarts with a question mark?:This is incorrect according to RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax. The question mark is a
delimiter, andquerydoes not include the question mark. .NET is the outlier for how it handlesUri.Query(see below), and it's been 18 years since theRFC 3986standard. This inconsistent usage of the question mark is likely a causative factor for the common inconsistent usage of the question mark in Azure SAS tokens.Uri.Fragmenthas this same issue too (it also incorrectly starts with a delimiter#).HTTP/1.1 [RFC 3986]
1.2.3. Hierarchical Identifiers
The generic syntax uses the slash ("/"), question mark ("?"), and number sign ("#") characters to delimit components that are significant to the generic parser's hierarchical interpretation of an identifier.
3. Syntax Components
Notice that in Java, Go, Python, and PHP, the canonical URI implementations do NOT include the
?in the query:Java
Result:
name=ferretGo
Result:
name=ferretPython
Result:
name=ferretPHP
Result:
name=ferretReproduction Steps
Expected behavior
It's expected that the question mark
?is not included in the string returned byuri.Query, so we should expect:However, a breaking change is not the correct solution to this (please see the Proposed Solution section below).
Actual behavior
Currently, the question mark is included in uri.Query:
Regression?
No,
Uri.Queryin .NET Framework 1.1 (February 2002) pre-dates RFC 3986 (January 2005). Although it's been a considerable amount of time, .NET is the outlier for how it handlesUri.Query, and it's been 18 years since theRFC 3986standard. This inconsistent usage of the question mark is likely a causative factor for the common inconsistent usage of the question mark in Azure SAS tokens.Known Workarounds
Configuration
No response
Other information
The root cause is here:
https://github.com/dotnet/runtime/blob/9aefa9daa141bb7d9ba3f2b373d4b050c9b243fe/src/libraries/System.Private.Uri/src/System/Uri.cs#L1091
| UriComponents.KeepDelimitercauses the delimiter to be included in bothUri.QueryandUri.Fragment.Proposed Solution
💡 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.