【问题标题】:MVC 2, IModelBinder & ValueProvider changesMVC 2、IModelBinder 和 ValueProvider 的变化
【发布时间】:2015-09-15 10:15:25
【问题描述】:

我正在尝试迁移到 ASP.Net MVC 2 并遇到一些问题。 这是一个: 我需要直接绑定 Dictionary 作为查看帖子的结果。

在 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
}

它与一些显示数据字典的智能 HtmlBuilder 配合使用。

我现在遇到的问题是 ValueProvider 不再是 Dictionary 了,它是一个 IValueProvider 只允许获取名称已知的值

public interface IValueProvider
{
    bool ContainsPrefix(string prefix);
    ValueProviderResult GetValue(string key);
}

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

问题:

  1. 还有其他获取所有密钥的方法吗?
  2. 您知道另一种将 HTML 元素集合绑定到字典的方法

感谢您的建议

哦。

【问题讨论】:

标签: asp.net-mvc-2 imodelbinder


【解决方案1】:

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

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.
}

【讨论】:

  • 我现在看到我的方法不允许对自定义模型绑定器进行简单的单元测试,因为 GetKeys 代码直接访问 Request.Form 和 Request.QueryString。我会检查我是否可以改进这一点。
【解决方案2】:

我认为在 MVC 2 中你不能再这样做了。
或者,您可以扩展 DefaultModelBinder 并覆盖其虚拟方法之一,例如 GetModelProperties,然后更改 ModelBindingContext 中的 ModelName。另一种选择是为您的 Dictionary 类型实现自定义 MetadataProvider,您也可以在那里更改模型名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    相关资源
    最近更新 更多