From bc43ccbc30b8265cf8b0efec9e7cf7892ef41622 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 18 Mar 2014 10:51:15 -0700 Subject: [PATCH] Change QueryString to include the leading '?'. --- .../QueryString.cs | 37 +++++++++++-------- .../Infrastructure/ParsingHelpers.cs | 4 ++ 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.AspNet.Abstractions/QueryString.cs b/src/Microsoft.AspNet.Abstractions/QueryString.cs index 9d96419788..0bca5c7262 100644 --- a/src/Microsoft.AspNet.Abstractions/QueryString.cs +++ b/src/Microsoft.AspNet.Abstractions/QueryString.cs @@ -15,27 +15,31 @@ namespace Microsoft.AspNet.Abstractions private readonly string _value; /// - /// Initalize the query string with a given value. This value must be in escaped and delimited format without + /// Initialize the query string with a given value. This value must be in escaped and delimited format with /// a leading '?' character. /// /// The query string to be assigned to the Value property. public QueryString(string value) { + if (!string.IsNullOrEmpty(value) && value[0] != '?') + { + throw new ArgumentException("The leading '?' must be included for a non-empty query."); + } _value = value; } /// - /// Initialize a query string with a single given parameter name and value. The value is + /// Initialize a query string with a single given parameter name and value. /// - /// The unencoded parameter name - /// The unencoded parameter value + /// The un-encoded parameter name + /// The un-encoded parameter value public QueryString(string name, string value) { - _value = Uri.EscapeDataString(name) + '=' + Uri.EscapeDataString(value); + _value = "?" + Uri.EscapeDataString(name) + '=' + Uri.EscapeDataString(value); } /// - /// The unescaped query string without the leading '?' character + /// The escaped query string with the leading '?' character /// public string Value { @@ -47,12 +51,12 @@ namespace Microsoft.AspNet.Abstractions /// public bool HasValue { - get { return !String.IsNullOrWhiteSpace(_value); } + get { return !String.IsNullOrEmpty(_value); } } /// /// Provides the query string escaped in a way which is correct for combining into the URI representation. - /// A leading '?' character will be prepended unless the Value is null or empty. Characters which are potentally + /// A leading '?' character will be included unless the Value is null or empty. Characters which are potentially /// dangerous are escaped. /// /// The query string value @@ -63,7 +67,7 @@ namespace Microsoft.AspNet.Abstractions /// /// Provides the query string escaped in a way which is correct for combining into the URI representation. - /// A leading '?' character will be prepended unless the Value is null or empty. Characters which are potentially + /// A leading '?' character will be included unless the Value is null or empty. Characters which are potentially /// dangerous are escaped. /// /// The query string value @@ -71,7 +75,7 @@ namespace Microsoft.AspNet.Abstractions public string ToUriComponent() { // Escape things properly so System.Uri doesn't mis-interpret the data. - return HasValue ? "?" + _value.Replace("#", "%23") : String.Empty; + return HasValue ? _value.Replace("#", "%23") : String.Empty; } /// @@ -87,11 +91,7 @@ namespace Microsoft.AspNet.Abstractions { return new QueryString(string.Empty); } - if (uriComponent[0] != '?') - { - throw new ArgumentException(""/*Resources.Exception_QueryStringMustStartWithDelimiter*/, "uriComponent"); - } - return new QueryString(uriComponent.Substring(1)); + return new QueryString(uriComponent); } /// @@ -105,7 +105,12 @@ namespace Microsoft.AspNet.Abstractions { throw new ArgumentNullException("uri"); } - return new QueryString(uri.GetComponents(UriComponents.Query, UriFormat.UriEscaped)); + string queryValue = uri.GetComponents(UriComponents.Query, UriFormat.UriEscaped); + if (!string.IsNullOrEmpty(queryValue)) + { + queryValue = "?" + queryValue; + } + return new QueryString(queryValue); } public bool Equals(QueryString other) diff --git a/src/Microsoft.AspNet.PipelineCore/Infrastructure/ParsingHelpers.cs b/src/Microsoft.AspNet.PipelineCore/Infrastructure/ParsingHelpers.cs index 7ab6b1c817..5f3f4f5bdb 100644 --- a/src/Microsoft.AspNet.PipelineCore/Infrastructure/ParsingHelpers.cs +++ b/src/Microsoft.AspNet.PipelineCore/Infrastructure/ParsingHelpers.cs @@ -803,6 +803,10 @@ namespace Microsoft.AspNet.PipelineCore.Infrastructure internal static IDictionary GetQuery(string queryString) { + if (!string.IsNullOrEmpty(queryString) && queryString[0] == '?') + { + queryString = queryString.Substring(1); + } var accumulator = new Dictionary>(StringComparer.OrdinalIgnoreCase); ParseDelimited(queryString, AmpersandAndSemicolon, AppendItemCallback, accumulator); return accumulator.ToDictionary(