Revert "Fix for issue 85 - Dictionary types should return null on key not found"

This is causing issues with routing functional tests in CoreCLR. Suspect
CoreCLR compat issue.

This reverts commit ae65001e84.
This commit is contained in:
Ryan Nowak 2014-07-25 14:35:36 -07:00
parent ae65001e84
commit 0e826e69e6
5 changed files with 22 additions and 215 deletions

View File

@ -2,48 +2,21 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
namespace Microsoft.AspNet.Routing namespace Microsoft.AspNet.Routing
{ {
/// <summary> public class RouteValueDictionary : Dictionary<string, object>
/// An <see cref="IDictionary{string, object}"/> type for route values.
/// </summary>
public class RouteValueDictionary : IDictionary<string, object>
{ {
private readonly Dictionary<string, object> _dictionary;
/// <summary>
/// Creates an empty RouteValueDictionary.
/// </summary>
public RouteValueDictionary() public RouteValueDictionary()
: base(StringComparer.OrdinalIgnoreCase)
{ {
_dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
} }
/// <summary>
/// Creates a RouteValueDictionary initialized with the provided input values.
/// </summary>
/// <param name="values">Input values to copy into the dictionary.</param>
public RouteValueDictionary([NotNull] IDictionary<string, object> values)
{
_dictionary = new Dictionary<string, object>(values, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Creates a RouteValueDictionary initialized with the provided input values.
/// </summary>
/// <param name="values">Input values to copy into the dictionary.</param>
/// <remarks>
/// The input parameter is interpreted as a set of key-value-pairs where the property names
/// are keys, and property values are the values, and copied into the dictionary. Only public
/// instance non-index properties are considered.
/// </remarks>
public RouteValueDictionary(object obj) public RouteValueDictionary(object obj)
: this() : base(StringComparer.OrdinalIgnoreCase)
{ {
if (obj != null) if (obj != null)
{ {
@ -73,162 +46,9 @@ namespace Microsoft.AspNet.Routing
} }
} }
/// <inheritdoc /> public RouteValueDictionary(IDictionary<string, object> other)
public object this[[NotNull] string key] : base(other, StringComparer.OrdinalIgnoreCase)
{ {
get
{
object value;
_dictionary.TryGetValue(key, out value);
return value;
}
set
{
_dictionary[key] = value;
}
}
/// <summary>
/// Gets the comparer for this dictionary.
/// </summary>
/// <remarks>
/// This will always be a reference to <see cref="StringComparer.OrdinalIgnoreCase"/>
/// </remarks>
public IEqualityComparer<string> Comparer
{
get
{
return _dictionary.Comparer;
}
}
/// <inheritdoc />
public int Count
{
get
{
return _dictionary.Count;
}
}
/// <inheritdoc />
bool ICollection<KeyValuePair<string, object>>.IsReadOnly
{
get
{
return ((ICollection<KeyValuePair<string, object>>)_dictionary).IsReadOnly;
}
}
/// <inheritdoc />
public Dictionary<string, object>.KeyCollection Keys
{
get
{
return _dictionary.Keys;
}
}
/// <inheritdoc />
ICollection<string> IDictionary<string, object>.Keys
{
get
{
return _dictionary.Keys;
}
}
/// <inheritdoc />
public Dictionary<string, object>.ValueCollection Values
{
get
{
return _dictionary.Values;
}
}
/// <inheritdoc />
ICollection<object> IDictionary<string, object>.Values
{
get
{
return _dictionary.Values;
}
}
/// <inheritdoc />
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
{
((ICollection<KeyValuePair<string, object>>)_dictionary).Add(item);
}
/// <inheritdoc />
public void Add([NotNull] string key, object value)
{
_dictionary.Add(key, value);
}
/// <inheritdoc />
public void Clear()
{
_dictionary.Clear();
}
/// <inheritdoc />
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
{
return ((ICollection<KeyValuePair<string, object>>)_dictionary).Contains(item);
}
/// <inheritdoc />
public bool ContainsKey([NotNull] string key)
{
return _dictionary.ContainsKey(key);
}
/// <inheritdoc />
void ICollection<KeyValuePair<string, object>>.CopyTo(
[NotNull] KeyValuePair<string, object>[] array,
int arrayIndex)
{
((ICollection<KeyValuePair<string, object>>)_dictionary).CopyTo(array, arrayIndex);
}
/// <inheritdoc />
public Dictionary<string, object>.Enumerator GetEnumerator()
{
return _dictionary.GetEnumerator();
}
/// <inheritdoc />
IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
/// <inheritdoc />
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
{
return ((ICollection<KeyValuePair<string, object>>)_dictionary).Remove(item);
}
/// <inheritdoc />
public bool Remove([NotNull] string key)
{
return _dictionary.Remove(key);
}
/// <inheritdoc />
public bool TryGetValue([NotNull] string key, out object value)
{
return _dictionary.TryGetValue(key, out value);
} }
} }
} }

View File

@ -147,7 +147,7 @@ namespace Microsoft.AspNet.Routing.Template
// Add any ambient values that don't match parameters - they need to be visible to constraints // Add any ambient values that don't match parameters - they need to be visible to constraints
// but they will ignored by link generation. // but they will ignored by link generation.
var combinedValues = new RouteValueDictionary(context.AcceptedValues); var combinedValues = new Dictionary<string, object>(context.AcceptedValues, StringComparer.OrdinalIgnoreCase);
if (ambientValues != null) if (ambientValues != null)
{ {
foreach (var kvp in ambientValues) foreach (var kvp in ambientValues)
@ -292,6 +292,7 @@ namespace Microsoft.AspNet.Routing.Template
return null; return null;
} }
/// <summary> /// <summary>
/// Compares two objects for equality as parts of a case-insensitive path. /// Compares two objects for equality as parts of a case-insensitive path.
/// </summary> /// </summary>
@ -341,8 +342,8 @@ namespace Microsoft.AspNet.Routing.Template
{ {
private readonly IDictionary<string, object> _defaults; private readonly IDictionary<string, object> _defaults;
private readonly RouteValueDictionary _acceptedValues; private readonly Dictionary<string, object> _acceptedValues;
private readonly RouteValueDictionary _filters; private readonly Dictionary<string, object> _filters;
public TemplateBindingContext(IDictionary<string, object> defaults, IDictionary<string, object> values) public TemplateBindingContext(IDictionary<string, object> defaults, IDictionary<string, object> values)
{ {
@ -353,20 +354,20 @@ namespace Microsoft.AspNet.Routing.Template
_defaults = defaults; _defaults = defaults;
_acceptedValues = new RouteValueDictionary(); _acceptedValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
if (_defaults != null) if (_defaults != null)
{ {
_filters = new RouteValueDictionary(defaults); _filters = new Dictionary<string, object>(defaults, StringComparer.OrdinalIgnoreCase);
} }
} }
public RouteValueDictionary AcceptedValues public Dictionary<string, object> AcceptedValues
{ {
get { return _acceptedValues; } get { return _acceptedValues; }
} }
public RouteValueDictionary Filters public Dictionary<string, object> Filters
{ {
get { return _filters; } get { return _filters; }
} }

View File

@ -32,10 +32,10 @@ namespace Microsoft.AspNet.Routing.Template
if (defaults == null) if (defaults == null)
{ {
defaults = new RouteValueDictionary(); defaults = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
} }
var values = new RouteValueDictionary(); var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
for (var i = 0; i < requestSegments.Length; i++) for (var i = 0; i < requestSegments.Length; i++)
{ {
@ -175,7 +175,7 @@ namespace Microsoft.AspNet.Routing.Template
private bool MatchComplexSegment(TemplateSegment routeSegment, private bool MatchComplexSegment(TemplateSegment routeSegment,
string requestSegment, string requestSegment,
IDictionary<string, object> defaults, IDictionary<string, object> defaults,
RouteValueDictionary values) Dictionary<string, object> values)
{ {
Contract.Assert(routeSegment != null); Contract.Assert(routeSegment != null);
Contract.Assert(routeSegment.Parts.Count > 1); Contract.Assert(routeSegment.Parts.Count > 1);

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Routing.Template
_target = target; _target = target;
_routeTemplate = routeTemplate ?? string.Empty; _routeTemplate = routeTemplate ?? string.Empty;
Name = routeName; Name = routeName;
_defaults = defaults ?? new RouteValueDictionary(); _defaults = defaults ?? new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
_constraints = RouteConstraintBuilder.BuildConstraints(constraints, _routeTemplate) ?? _constraints = RouteConstraintBuilder.BuildConstraints(constraints, _routeTemplate) ??
new Dictionary<string, IRouteConstraint>(); new Dictionary<string, IRouteConstraint>();

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
// PathString in HttpAbstractions guarantees a leading slash - so no value in testing other cases. // PathString in HttpAbstractions guarantees a leading slash - so no value in testing other cases.
[Fact] [Fact]
public async Task Match_Success_LeadingSlash() public async void Match_Success_LeadingSlash()
{ {
// Arrange // Arrange
var route = CreateRoute("{controller}/{action}"); var route = CreateRoute("{controller}/{action}");
@ -40,7 +40,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
} }
[Fact] [Fact]
public async Task Match_Success_RootUrl() public async void Match_Success_RootUrl()
{ {
// Arrange // Arrange
var route = CreateRoute(""); var route = CreateRoute("");
@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
} }
[Fact] [Fact]
public async Task Match_Success_Defaults() public async void Match_Success_Defaults()
{ {
// Arrange // Arrange
var route = CreateRoute("{controller}/{action}", new { action = "Index" }); var route = CreateRoute("{controller}/{action}", new { action = "Index" });
@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
} }
[Fact] [Fact]
public async Task Match_Fails() public async void Match_Fails()
{ {
// Arrange // Arrange
var route = CreateRoute("{controller}/{action}"); var route = CreateRoute("{controller}/{action}");
@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests
} }
[Fact] [Fact]
public async Task Match_RejectedByHandler() public async void Match_RejectedByHandler()
{ {
// Arrange // Arrange
var route = CreateRoute("{controller}", accept: false); var route = CreateRoute("{controller}", accept: false);
@ -102,20 +102,6 @@ namespace Microsoft.AspNet.Routing.Template.Tests
Assert.NotNull(context.RouteData.Values); Assert.NotNull(context.RouteData.Values);
} }
[Fact]
public async Task Match_RouteValuesDoesntThrowOnKeyNotFound()
{
// Arrange
var route = CreateRoute("{controller}/{action}");
var context = CreateRouteContext("/Home/Index");
// Act
await route.RouteAsync(context);
// Assert
Assert.Null(context.RouteData.Values["1controller"]);
}
private static RouteContext CreateRouteContext(string requestPath) private static RouteContext CreateRouteContext(string requestPath)
{ {
var request = new Mock<HttpRequest>(MockBehavior.Strict); var request = new Mock<HttpRequest>(MockBehavior.Strict);