Asp.net mvc 2 MVC 2、IModelBinder&;ValueProvider更改

Asp.net mvc 2 MVC 2、IModelBinder&;ValueProvider更改,asp.net-mvc-2,imodelbinder,Asp.net Mvc 2,Imodelbinder,我正在尝试迁移到ASP.NETMVC2并遇到一些问题。 这里有一个: 作为查看帖子的结果,我需要直接绑定一个字典 在ASP.Net MVC 1中,使用自定义的IModelBinder,它可以完美地工作: /// <summary> /// Bind Dictionary<int, int> /// /// convention : <elm name="modelName_key" value="value"></elm> /// </su

我正在尝试迁移到ASP.NETMVC2并遇到一些问题。 这里有一个: 作为查看帖子的结果,我需要直接绑定一个字典

在ASP.Net MVC 1中,使用自定义的IModelBinder,它可以完美地工作:

/// <summary>
/// Bind Dictionary<int, int>
/// 
/// convention : <elm name="modelName_key" value="value"></elm>
/// </summary>
public class DictionaryModelBinder : IModelBinder
{
    #region IModelBinder Members

    /// <summary>
    /// Mandatory
    /// </summary>
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        IDictionary<int, int> retour = new Dictionary<int, int>();

        // get the values
        var values = bindingContext.ValueProvider;
        // get the model name
        string modelname = bindingContext.ModelName + '_';
        int skip = modelname.Length;

        // loop on the keys
        foreach(string keyStr in values.Keys)
        {
            // if an element has been identified
            if(keyStr.StartsWith(modelname))
            {
                // get that key
                int key;
                if(Int32.TryParse(keyStr.Substring(skip), out key))
                {
                    int value;
                    if(Int32.TryParse(values[keyStr].AttemptedValue, out value))
                        retour.Add(key, value);
                }
            }
        }
        return retour;
    }

    #endregion
}
这真的不酷,因为我无法执行智能解析

问题:

  • 有没有别的办法拿到所有的钥匙
  • 您知道将HTML元素集合绑定到字典的另一种方法吗
  • 谢谢你的建议


    O.

    我认为在MVC2中,您将无法再以这种方式进行操作。

    或者,您可以扩展DefaultModelBinder并重写它的一个虚拟方法,如GetModelProperties,然后在ModelBindingContext中更改ModelName。另一种选择是为您的字典类型实现自定义元数据提供程序,您也可以在那里更改模型名称。

    尽管此问题已标记为“已回答”,但我认为以下内容可能会有所帮助。 我遇到了同样的问题,并查看了System.Web.Mvc.DefaultValueProvider的源代码。它从RouteData、查询字符串或请求表单提交(按确切顺序)获取其值。为了收集所有的密钥(这是您在第一个问题中要求的),我编写了以下helper方法

    private static IEnumerable<string> GetKeys(ControllerContext context)
    {
        List<string> keys = new List<string>();
        HttpRequestBase request = context.HttpContext.Request;
        keys.AddRange(((IDictionary<string,
            object>)context.RouteData.Values).Keys.Cast<string>());
        keys.AddRange(request.QueryString.Keys.Cast<string>());
        keys.AddRange(request.Form.Keys.Cast<string>());
        return keys;
    }
    

    请看这里:我现在看到,我的方法不允许对自定义模型绑定器进行简单的单元测试,因为GetKeys代码直接访问Request.Form和Request.QueryString。我会检查我是否能在这方面有所改进。
    private static IEnumerable<string> GetKeys(ControllerContext context)
    {
        List<string> keys = new List<string>();
        HttpRequestBase request = context.HttpContext.Request;
        keys.AddRange(((IDictionary<string,
            object>)context.RouteData.Values).Keys.Cast<string>());
        keys.AddRange(request.QueryString.Keys.Cast<string>());
        keys.AddRange(request.Form.Keys.Cast<string>());
        return keys;
    }
    
    foreach (string key in GetKeys(controllerContext))
    {
        // Do something with the key value.
    }