Fix RouteValueDictionary to handle read-only dictionaries.
This commit is contained in:
parent
f6e48d0080
commit
1f6d3fe4cc
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Routing
|
|||
private readonly Dictionary<string, object> _dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty RouteValueDictionary.
|
||||
/// Creates an empty <see cref="RouteValueDictionary"/>.
|
||||
/// </summary>
|
||||
public RouteValueDictionary()
|
||||
{
|
||||
|
|
@ -31,28 +31,32 @@ namespace Microsoft.AspNet.Routing
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RouteValueDictionary initialized with the provided input values.
|
||||
/// Creates a <see cref="RouteValueDictionary"/> initialized with the provided input value.
|
||||
/// </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>
|
||||
/// <param name="obj">An object to initialize the dictionary. The value can be of type
|
||||
/// <see cref="IDictionary{TKey, TValue}"/> or <see cref="IReadOnlyDictionary{TKey, TValue}"/> or
|
||||
/// any other object.
|
||||
/// </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.
|
||||
/// If the value is a dictionary, then its entries are copied. Otherwise the object 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)
|
||||
: this()
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
var keyValuePairCollection = obj as IEnumerable<KeyValuePair<string, object>>;
|
||||
if (keyValuePairCollection != null)
|
||||
{
|
||||
foreach (var kvp in keyValuePairCollection)
|
||||
{
|
||||
Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var type = obj.GetType();
|
||||
var allProperties = type.GetRuntimeProperties();
|
||||
|
||||
|
|
|
|||
|
|
@ -370,11 +370,7 @@ namespace Microsoft.AspNet.Routing.Template
|
|||
|
||||
if (_defaults != null)
|
||||
{
|
||||
_filters = new RouteValueDictionary(defaults);
|
||||
foreach (var kvp in _defaults)
|
||||
{
|
||||
_filters.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
_filters = new RouteValueDictionary(_defaults);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,48 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateFromReadOnlyDictionary_CopiesValues()
|
||||
{
|
||||
// Arrange
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
dictionary.Add("Name", "James");
|
||||
dictionary.Add("Age", 30);
|
||||
var readonlyDictionary = (IReadOnlyDictionary<string, object>)dictionary;
|
||||
|
||||
// Act
|
||||
var dict = new RouteValueDictionary(readonlyDictionary);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, dict.Count);
|
||||
Assert.Equal("James", dict["Name"]);
|
||||
Assert.Equal(30, dict["Age"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateFromReadOnlyDictionary_ModifyRouteValueDictionary()
|
||||
{
|
||||
// Arrange
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
dictionary.Add("Name", "James");
|
||||
dictionary.Add("Age", 30);
|
||||
dictionary.Add("Address", new Address() { City = "Redmond", State = "WA" });
|
||||
var readonlyDictionary = (IReadOnlyDictionary<string, object>)dictionary;
|
||||
|
||||
// Act
|
||||
var routeValueDictionary = new RouteValueDictionary(readonlyDictionary);
|
||||
routeValueDictionary.Add("City", "Redmond");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(4, routeValueDictionary.Count);
|
||||
Assert.Equal("James", routeValueDictionary["Name"]);
|
||||
Assert.Equal(30, routeValueDictionary["Age"]);
|
||||
Assert.Equal("Redmond", routeValueDictionary["City"]);
|
||||
var address = Assert.IsType<Address>(routeValueDictionary["Address"]);
|
||||
address.State = "Washington";
|
||||
Assert.Equal("Washington", ((Address)routeValueDictionary["Address"]).State);
|
||||
}
|
||||
|
||||
private static string GetDuplicateKeyErrorMessage()
|
||||
{
|
||||
// Gets the exception message when duplicate entries are
|
||||
|
|
@ -233,5 +275,12 @@ namespace Microsoft.AspNet.Routing.Tests
|
|||
set { }
|
||||
}
|
||||
}
|
||||
|
||||
private class Address
|
||||
{
|
||||
public string City { get; set; }
|
||||
|
||||
public string State { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue