From f2e6c294b02b0ab8fb49bf0535f7c248451fb3ba Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Mon, 4 May 2015 10:21:29 -0700 Subject: [PATCH] Address feedback for PR: https://github.com/aspnet/Routing/pull/182 --- .../RouteValueDictionary.cs | 25 ++++---- .../Template/TemplateBinder.cs | 2 +- .../RouteValueDictionaryTests.cs | 58 +++++++++++-------- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/Microsoft.AspNet.Routing/RouteValueDictionary.cs b/src/Microsoft.AspNet.Routing/RouteValueDictionary.cs index 8f6457cce0..e528c1ecdc 100644 --- a/src/Microsoft.AspNet.Routing/RouteValueDictionary.cs +++ b/src/Microsoft.AspNet.Routing/RouteValueDictionary.cs @@ -31,23 +31,24 @@ namespace Microsoft.AspNet.Routing } /// - /// Creates a initialized with the provided input value. + /// Creates a initialized with the specified . /// - /// An object to initialize the dictionary. The value can be of type - /// or or - /// any other object. + /// An object to initialize the dictionary. The value can be of type + /// or + /// or an object with public properties as key-value pairs. /// /// - /// 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. + /// If the value is a dictionary or other , + /// 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. /// - public RouteValueDictionary(object obj) + public RouteValueDictionary(object values) : this() { - if (obj != null) + if (values != null) { - var keyValuePairCollection = obj as IEnumerable>; + var keyValuePairCollection = values as IEnumerable>; if (keyValuePairCollection != null) { foreach (var kvp in keyValuePairCollection) @@ -57,7 +58,7 @@ namespace Microsoft.AspNet.Routing return; } - var type = obj.GetType(); + var type = values.GetType(); var allProperties = type.GetRuntimeProperties(); // This is done to support 'new' properties that hide a property on a base class @@ -69,7 +70,7 @@ namespace Microsoft.AspNet.Routing !property.GetMethod.IsStatic && property.GetIndexParameters().Length == 0) { - var value = property.GetValue(obj); + var value = property.GetValue(values); if (ContainsKey(property.Name) && property.DeclaringType != type) { // This is a hidden property, ignore it. diff --git a/src/Microsoft.AspNet.Routing/Template/TemplateBinder.cs b/src/Microsoft.AspNet.Routing/Template/TemplateBinder.cs index 30ada5cf37..779496f9a2 100644 --- a/src/Microsoft.AspNet.Routing/Template/TemplateBinder.cs +++ b/src/Microsoft.AspNet.Routing/Template/TemplateBinder.cs @@ -414,7 +414,7 @@ namespace Microsoft.AspNet.Routing.Template return string.Format( "{{Accepted: '{0}' Filters: '{1}'}}", string.Join(", ", _acceptedValues.Keys), - string.Join(", ", _filters.Keys)); + string.Join(", ", _filters?.Keys)); } } diff --git a/test/Microsoft.AspNet.Routing.Tests/RouteValueDictionaryTests.cs b/test/Microsoft.AspNet.Routing.Tests/RouteValueDictionaryTests.cs index 4015158aa8..88dd3ac4f0 100644 --- a/test/Microsoft.AspNet.Routing.Tests/RouteValueDictionaryTests.cs +++ b/test/Microsoft.AspNet.Routing.Tests/RouteValueDictionaryTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Linq; using System.Collections.Generic; using Microsoft.AspNet.Testing; using Xunit; @@ -168,36 +169,47 @@ namespace Microsoft.AspNet.Routing.Tests expected); } - [Fact] - public void CreateFromReadOnlyDictionary_CopiesValues() + public static IEnumerable IEnumerableKeyValuePairData { - // Arrange - var dictionary = new Dictionary(); - dictionary.Add("Name", "James"); - dictionary.Add("Age", 30); - var readonlyDictionary = (IReadOnlyDictionary)dictionary; + get + { + var routeValues = new[] + { + new KeyValuePair("Name", "James"), + new KeyValuePair("Age", 30), + new KeyValuePair("Address", new Address() { City = "Redmond", State = "WA" }) + }; - // Act - var dict = new RouteValueDictionary(readonlyDictionary); + yield return new object[] { routeValues.ToDictionary(kvp => kvp.Key, kvp => kvp.Value) }; - // Assert - Assert.Equal(2, dict.Count); - Assert.Equal("James", dict["Name"]); - Assert.Equal(30, dict["Age"]); + yield return new object[] { routeValues.ToList() }; + + yield return new object[] { routeValues }; + } } - [Fact] - public void CreateFromReadOnlyDictionary_ModifyRouteValueDictionary() + [Theory] + [MemberData(nameof(IEnumerableKeyValuePairData))] + public void RouteValueDictionary_CopiesValues_FromIEnumerableKeyValuePair(object values) { - // Arrange - var dictionary = new Dictionary(); - dictionary.Add("Name", "James"); - dictionary.Add("Age", 30); - dictionary.Add("Address", new Address() { City = "Redmond", State = "WA" }); - var readonlyDictionary = (IReadOnlyDictionary)dictionary; + // Arrange & Act + var dict = new RouteValueDictionary(values); - // Act - var routeValueDictionary = new RouteValueDictionary(readonlyDictionary); + // Assert + Assert.Equal(3, dict.Count); + Assert.Equal("James", dict["Name"]); + Assert.Equal(30, dict["Age"]); + var address = Assert.IsType
(dict["Address"]); + Assert.Equal("Redmond", address.City); + Assert.Equal("WA", address.State); + } + + [Theory] + [MemberData(nameof(IEnumerableKeyValuePairData))] + public void CreatedFrom_IEnumerableKeyValuePair_AllowsAddingOrModifyingValues(object values) + { + // Arrange & Act + var routeValueDictionary = new RouteValueDictionary(values); routeValueDictionary.Add("City", "Redmond"); // Assert