MVC3字典未绑定到模型 [英] MVC3 Dictionary not binding to model

查看:81
本文介绍了MVC3字典未绑定到模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含字典属性的模型. (这已从一个较大的项目中提取到了这个示例中,我已经确认仍然存在相同的问题)

I have a model that contains a dictionary property. (this has been distilled from a larger project into this example, which I have confirmed still has the same issue)

public class TestModel
{
    public IDictionary<string, string> Values { get; set; }

    public TestModel()
    {
        Values = new Dictionary<string, string>();
    }
}

控制器

public class TestController : Controller
{
    public ActionResult Index()
    {
        TestModel model = new TestModel();
        model.Values.Add("foo", "bar");
        model.Values.Add("fizz", "buzz");
        model.Values.Add("hello", "world");

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(TestModel model)
    {
        // model.Values is null after post back here.
        return null; // I set a break point here to inspect 'model'
    }
}

和一个视图

@using TestMVC.Models
@model TestModel
@using (Html.BeginForm())
{
    @Html.EditorFor(m => m.Values["foo"]);
    <br />
    @Html.EditorFor(m => m.Values["fizz"]);
    <br />
    @Html.EditorFor(m => m.Values["hello"]);
    <br />
    <input type="submit" value="submit" />
}

这将呈现给浏览器,如下所示:

This renders to the browser like this:

<input class="text-box single-line" id="Values_foo_" name="Values[foo]" type="text" value="bar" />

我遇到的问题是回发后字典在模型上为null.

The problem I'm having is that the dictionary is null on the model after postback.

  • 我这样做正确吗,还是有更好的方法?

我需要某种键值存储,因为表单上的字段是可变的,所以我不能使用POCO模型.

I need to have some kind of key-value storage, as the fields on my form are variable, so I can't use a POCO model.

推荐答案

正如@Blast_Dan和@gprasant所述,模型绑定程序期望输入元素的名称属性采用Property[index].Value格式,其中indexint,而ValueKeyValuePair类的属性之一.

As @Blast_Dan and @gprasant mentioned, the model binder is expecting the name attribute of the input element to be in the format Property[index].Value, where index is an int and Value is one of the properties on the KeyValuePair class.

不幸的是,@Html.EditorFor以错误的格式生成了该值.我写了一个HtmlHelper扩展名,将name属性转换为正确的格式:

Unfortunately, @Html.EditorFor generates this value in the wrong format. I wrote an HtmlHelper extension to transform the name attribute to the correct format:

public static IHtmlString DictionaryEditorFor<TModel, TProperty, TKey, TValue>(this HtmlHelper<TModel> Html, Expression<Func<TModel, TProperty>> expression, IDictionary<TKey, TValue> dictionary, DictionaryIndexRetrievalCounter<TKey, TValue> counter, string templateName, object additionalViewData)
{
    string hiddenKey = Html.HiddenFor(expression).ToHtmlString();
    string editorValue = Html.EditorFor(expression, templateName, additionalViewData).ToHtmlString();
    string expText = ExpressionHelper.GetExpressionText(expression);
    string indexText = expText.Substring(expText.IndexOf('[')).Replace("[", string.Empty).Replace("]", string.Empty);

    KeyValuePair<TKey, TValue> item = dictionary.SingleOrDefault(p => p.Key.ToString() == indexText);
    int index = counter.GetIndex(item.Key);

    string key = hiddenKey.Replace("[" + indexText + "]", "[" + index + "].Key").Replace("value=\"" + item.Value + "\"", "value=\"" + item.Key + "\"");

    string value = editorValue.Replace("[" + indexText + "]", "[" + index + "].Value");

    return new HtmlString(key + value);
}

因为整数索引必须遵循以下规则:

Because the integer index must follow these rules:

  1. 必须从0开始

  1. Must start with 0

必须不间断(例如,您不能从3跳到5)

Must be unbroken (you can't skip from 3 to 5, for example)

我写了一个计数器类来为我处理整数索引:

I wrote a counter class to handle getting the integer index for me:

public class DictionaryIndexRetrievalCounter<TKey, TValue>
{
    private IDictionary<TKey, TValue> _dictionary;
    private IList<TKey> _retrievedKeys;

    public DictionaryIndexRetrievalCounter(IDictionary<TKey, TValue> dictionary)
    {
        this._dictionary = dictionary;
        this._retrievedKeys = new List<TKey>();
    }

    public int GetIndex(TKey key)
    {
        if (!_retrievedKeys.Contains(key))
        {
            _retrievedKeys.Add(key);
        }

        return _retrievedKeys.IndexOf(key);
    }
}

这篇关于MVC3字典未绑定到模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆