I was wondering if there is an elegant way to add an array of complex types to a RouteValueDictionary or compatible type?
For example, if I have a class and an actio
I ran into this problem as well and used Zack's code but found a bug in it. If the IEnumerable is an array of string (string[]) then there is a problem. So i thaught I'd share my extended version.
public static RouteValueDictionary ToRouteValueDictionaryWithCollection(this RouteValueDictionary routeValues)
{
var newRouteValues = new RouteValueDictionary();
foreach(var key in routeValues.Keys)
{
object value = routeValues[key];
if(value is IEnumerable && !(value is string))
{
int index = 0;
foreach(object val in (IEnumerable)value)
{
if(val is string || val.GetType().IsPrimitive)
{
newRouteValues.Add(String.Format("{0}[{1}]", key, index), val);
}
else
{
var properties = val.GetType().GetProperties();
foreach(var propInfo in properties)
{
newRouteValues.Add(
String.Format("{0}[{1}].{2}", key, index, propInfo.Name),
propInfo.GetValue(val));
}
}
index++;
}
}
else
{
newRouteValues.Add(key, value);
}
}
return newRouteValues;
}
Well, I am open to other (more elegant) solutions, but I did get it working by taking the extension method found at this q/a: https://stackoverflow.com/a/5208050/1228414 and adapting it to use reflection for complex type properties instead of assuming primitive type arrays.
My code:
public static RouteValueDictionary ToRouteValueDictionaryWithCollection(this RouteValueDictionary routeValues)
{
RouteValueDictionary newRouteValues = new RouteValueDictionary();
foreach (var key in routeValues.Keys)
{
object value = routeValues[key];
if (value is IEnumerable && !(value is string))
{
int index = 0;
foreach (object val in (IEnumerable)value)
{
PropertyInfo[] properties = val.GetType().GetProperties();
foreach (PropertyInfo propInfo in properties)
{
newRouteValues.Add(
String.Format("{0}[{1}].{2}", key, index, propInfo.Name),
propInfo.GetValue(val));
}
index++;
}
}
else
{
newRouteValues.Add(key, value);
}
}
return newRouteValues;
}