diff --git a/src/Microsoft.AspNet.Mvc.Core/Internal/TypeHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Internal/TypeHelper.cs index 16a93a5c9f..67b3568a56 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Internal/TypeHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Internal/TypeHelper.cs @@ -31,13 +31,22 @@ namespace Microsoft.AspNet.Mvc /// /// Given an object, adds each instance property with a public get method as a key and its /// associated value to a dictionary. + /// + /// If the object is already an instance, then a copy + /// is returned. /// // // The implementation of PropertyHelper will cache the property accessors per-type. This is // faster when the the same type is used multiple times with ObjectToDictionary. public static IDictionary ObjectToDictionary(object value) { - var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + var dictionary = value as IDictionary; + if (dictionary != null) + { + return new Dictionary(dictionary, StringComparer.OrdinalIgnoreCase); + } + + dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); if (value != null) { diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs index d0ff591f80..b2f996417b 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs @@ -103,6 +103,9 @@ namespace Microsoft.AspNet.Mvc.Rendering /// Creates a dictionary from an object, by adding each public instance property as a key with its associated /// value to the dictionary. It will expose public properties from derived types as well. This is typically used /// with objects of an anonymous type. + /// + /// If the object is already an instance, then it is + /// returned as-is. /// /// /// new { property_name = "value" } will translate to the entry { "property_name" , "value" } @@ -112,32 +115,15 @@ namespace Microsoft.AspNet.Mvc.Rendering /// The created dictionary of property names and property values. public static IDictionary ObjectToDictionary(object obj) { - IDictionary result; - var valuesAsDictionary = obj as IDictionary; - if (valuesAsDictionary != null) - { - result = new Dictionary(valuesAsDictionary, StringComparer.OrdinalIgnoreCase); - } - else - { - result = new Dictionary(StringComparer.OrdinalIgnoreCase); - - if (obj != null) - { - foreach (var prop in obj.GetType().GetRuntimeProperties()) - { - var value = prop.GetValue(obj); - result.Add(prop.Name, value); - } - } - } - - return result; + return TypeHelper.ObjectToDictionary(obj); } /// /// Creates a dictionary of HTML attributes from the input object, - /// translating underscores to dashes. + /// translating underscores to dashes in each public instance property. + /// + /// If the object is already an instance, then it is + /// returned as-is. /// /// new { data_name="value" } will translate to the entry { "data-name" , "value" } /// in the resulting dictionary. @@ -147,9 +133,23 @@ namespace Microsoft.AspNet.Mvc.Rendering /// A dictionary that represents HTML attributes. public static IDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes) { - // NOTE: This should be doing more than just returning a generic conversion from obj -> dict - // Once GitHub #80 has been completed this will do more than be a call through. - return ObjectToDictionary(htmlAttributes); + var dictionary = htmlAttributes as IDictionary; + if (dictionary != null) + { + return new Dictionary(dictionary, StringComparer.OrdinalIgnoreCase); + } + + dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (htmlAttributes != null) + { + foreach (var helper in HtmlAttributePropertyHelper.GetProperties(htmlAttributes)) + { + dictionary.Add(helper.Name, helper.GetValue(htmlAttributes)); + } + } + + return dictionary; } public virtual void Contextualize([NotNull] ViewContext viewContext) @@ -164,11 +164,7 @@ namespace Microsoft.AspNet.Mvc.Rendering IDictionary htmlAttributeDictionary = null; if (htmlAttributes != null) { - htmlAttributeDictionary = htmlAttributes as IDictionary; - if (htmlAttributeDictionary == null) - { - htmlAttributeDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); - } + htmlAttributeDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); } return GenerateForm(actionName, controllerName, routeValues, method, htmlAttributeDictionary); diff --git a/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs index 6f1acf7469..0a07aea650 100644 --- a/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Globalization; using System.Linq; +using System.Linq.Expressions; using Microsoft.AspNet.Abstractions; using Microsoft.AspNet.DependencyInjection; using Microsoft.AspNet.Mvc.Rendering; @@ -27,15 +28,7 @@ namespace Microsoft.AspNet.Mvc public string Action(string action, string controller, object values, string protocol, string host, string fragment) { - var valuesDictionary = values as IDictionary; - if (valuesDictionary == null) - { - valuesDictionary = new RouteValueDictionary(values); - } - else - { - valuesDictionary = new RouteValueDictionary(valuesDictionary); - } + var valuesDictionary = TypeHelper.ObjectToDictionary(values); if (action != null) { @@ -76,7 +69,9 @@ namespace Microsoft.AspNet.Mvc public string RouteUrl(object values, string protocol, string host, string fragment) { - var path = GeneratePathFromRoute(new RouteValueDictionary(values)); + var valuesDictionary = TypeHelper.ObjectToDictionary(values); + + var path = GeneratePathFromRoute(valuesDictionary); if (path == null) { return null;