Change QueryString to include the leading '?'.

This commit is contained in:
Chris Ross 2014-03-18 10:51:15 -07:00
parent fc8832f69f
commit bc43ccbc30
2 changed files with 25 additions and 16 deletions

View File

@ -15,27 +15,31 @@ namespace Microsoft.AspNet.Abstractions
private readonly string _value; private readonly string _value;
/// <summary> /// <summary>
/// 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. /// a leading '?' character.
/// </summary> /// </summary>
/// <param name="value">The query string to be assigned to the Value property.</param> /// <param name="value">The query string to be assigned to the Value property.</param>
public QueryString(string value) 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; _value = value;
} }
/// <summary> /// <summary>
/// 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.
/// </summary> /// </summary>
/// <param name="name">The unencoded parameter name</param> /// <param name="name">The un-encoded parameter name</param>
/// <param name="value">The unencoded parameter value</param> /// <param name="value">The un-encoded parameter value</param>
public QueryString(string name, string value) public QueryString(string name, string value)
{ {
_value = Uri.EscapeDataString(name) + '=' + Uri.EscapeDataString(value); _value = "?" + Uri.EscapeDataString(name) + '=' + Uri.EscapeDataString(value);
} }
/// <summary> /// <summary>
/// The unescaped query string without the leading '?' character /// The escaped query string with the leading '?' character
/// </summary> /// </summary>
public string Value public string Value
{ {
@ -47,12 +51,12 @@ namespace Microsoft.AspNet.Abstractions
/// </summary> /// </summary>
public bool HasValue public bool HasValue
{ {
get { return !String.IsNullOrWhiteSpace(_value); } get { return !String.IsNullOrEmpty(_value); }
} }
/// <summary> /// <summary>
/// Provides the query string escaped in a way which is correct for combining into the URI representation. /// 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. /// dangerous are escaped.
/// </summary> /// </summary>
/// <returns>The query string value</returns> /// <returns>The query string value</returns>
@ -63,7 +67,7 @@ namespace Microsoft.AspNet.Abstractions
/// <summary> /// <summary>
/// Provides the query string escaped in a way which is correct for combining into the URI representation. /// 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. /// dangerous are escaped.
/// </summary> /// </summary>
/// <returns>The query string value</returns> /// <returns>The query string value</returns>
@ -71,7 +75,7 @@ namespace Microsoft.AspNet.Abstractions
public string ToUriComponent() public string ToUriComponent()
{ {
// Escape things properly so System.Uri doesn't mis-interpret the data. // 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;
} }
/// <summary> /// <summary>
@ -87,11 +91,7 @@ namespace Microsoft.AspNet.Abstractions
{ {
return new QueryString(string.Empty); return new QueryString(string.Empty);
} }
if (uriComponent[0] != '?') return new QueryString(uriComponent);
{
throw new ArgumentException(""/*Resources.Exception_QueryStringMustStartWithDelimiter*/, "uriComponent");
}
return new QueryString(uriComponent.Substring(1));
} }
/// <summary> /// <summary>
@ -105,7 +105,12 @@ namespace Microsoft.AspNet.Abstractions
{ {
throw new ArgumentNullException("uri"); 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) public bool Equals(QueryString other)

View File

@ -803,6 +803,10 @@ namespace Microsoft.AspNet.PipelineCore.Infrastructure
internal static IDictionary<string, string[]> GetQuery(string queryString) internal static IDictionary<string, string[]> GetQuery(string queryString)
{ {
if (!string.IsNullOrEmpty(queryString) && queryString[0] == '?')
{
queryString = queryString.Substring(1);
}
var accumulator = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); var accumulator = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
ParseDelimited(queryString, AmpersandAndSemicolon, AppendItemCallback, accumulator); ParseDelimited(queryString, AmpersandAndSemicolon, AppendItemCallback, accumulator);
return accumulator.ToDictionary( return accumulator.ToDictionary(