Zac*_* Z. 2 asp.net-mvc asp.net-mvc-4
我想知道是否有一种优雅的方法可以将一组复杂类型添加到RouteValueDictionary或兼容类型?
例如,如果我有一个类和一个动作:
public class TestObject
{
public string Name { get; set; }
public int Count { get; set; }
public TestObject()
{
}
public TestObject(string name, int count)
{
this.Name = name;
this.Count = count;
}
}
public ActionResult Test(ICollection<TestObjects> t)
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
然后我知道如果我通过URL"/Test?t[0].Name=One&t[0].Count=1&t[1].Name=Two&t[1].Count=2"调用此动作,MVC将映射那些查询字符串参数自动返回ICollection类型.但是,如果我使用Url.Action()在某处手动创建链接,并且我想传递参数的RouteValueDictionary,当我向RouteValueDictionary添加ICollection时,Url.Action只是将其呈现为类型,如&t = System.Collections.Generic.List.
例如:
RouteValueDictionary routeValDict = new RouteValueDictionary();
List<TestObject> testObjects = new List<TestObject>();
testObjects.Add(new TestObject("One", 1));
testObjects.Add(new TestObject("Two", 2));
routeValDict.Add("t", testObjects);
// Does not properly create the parameters for the List<TestObject> collection.
string url = Url.Action("Test", "Test", routeValDict);
Run Code Online (Sandbox Code Playgroud)
有没有办法让它自动将该集合呈现为MVC也理解如何映射的格式,或者我必须手动执行此操作?
我错过了什么,为什么他们会这样做,所以这个美丽的映射存在于一个Action中,但没有提供一种手动反向创建URL的方法?
好吧,我对其他(更优雅)的解决方案持开放态度,但我确实通过采用此q/a中的扩展方法来实现它:https://stackoverflow.com/a/5208050/1228414并使其适应使用反射对于复杂类型属性而不是假设基本类型数组.
我的代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
我也遇到了这个问题,并使用了Zack的代码,但发现了一个错误.如果IEnumerable是一个字符串数组(string []),则存在问题.所以我认为我会分享我的扩展版本.
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5348 次 |
| 最近记录: |