【问题标题】:Adding array of complex types to RouteValueDictionary将复杂类型的数组添加到 RouteValueDictionary
【发布时间】:2013-11-13 17:28:31
【问题描述】:

我想知道是否有一种优雅的方法可以将复杂类型的数组添加到 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();
}

然后我知道,如果我通过 URL "/Test?t[0].Name=One&t[0].Count=1&t[1].Name=Two&t[1].Count=2" 调用此操作, MVC 会自动将这些查询字符串参数映射回 ICollection 类型。但是,如果我使用 Url.Action() 在某处手动创建链接,并且我想传递参数的 RouteValueDictionary,那么当我将 ICollection 添加到 RouteValueDictionary 时,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);    

有没有办法让它自动将该集合呈现为 MVC 也理解如何映射的格式,或者我必须手动执行此操作?

我错过了什么,他们为什么要制作这样一个漂亮的映射存在于一个动作中,但不提供一种手动创建 URL 的相反方向的方法?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    我也遇到了这个问题,并使用了 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;
        }
    

    【讨论】:

    • 不错!感谢您的修复。
    • 我必须更改上面的代码才能在我的系统上编译:propInfo.GetValue(val, null));
    【解决方案2】:

    好吧,我对其他(更优雅的)解决方案持开放态度,但我确实通过采用在此 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多