0

所以我有一个包含字典属性列表的 ViewModel

public class ViewModel
{
    public List<Dictionary<int, bool>> Columns { get; set; }
}

我试图从视图中取回这个模型,并且它一直返回带有空项目的列表。

@Html.Hidden(String.Format("Columns[{0}][{1}].Key", i, firstItem.Id), firstItem.Id)
@Html.CheckBox(String.Format("Columns[{0}][{1}].Value", i, firstItem.Id), Model.Columns[i][firstItem.Id])

这不起作用。

@Html.CheckBoxFor(m => m.Columns[i][firstItem.Id])

这也行不通。

我做错了什么?

4

1 回答 1

1

您的 ViewModel 非常复杂,因为它包含嵌套集合,我认为无法使用默认模型绑定器将输入值绑定到模型。您应该创建自定义模型绑定器,我尝试实现自定义模型绑定器,这是我的实现 ListDictionary 模型绑定器:

自定义模型绑定器

    public class ListDictionaryModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var resultList = new List<Dictionary<int, bool>>();
            var forms = controllerContext.HttpContext.Request.Form;
            var regex = new Regex(@"(true,)?false");
            var result =
                forms.AllKeys.Select(x => new {key = x, value = forms[x]}).Where(x => x.key.Contains("Columns")).ToList();
            result.ForEach(x =>
                               {
                                   var matches = regex.Matches(x.value);
                                   var dictionary = new Dictionary<int, bool>();
                                   for (var i = 0; i < matches.Count; i++)
                                   {
                                       var value = matches[i].ToString() == "true,false" ? true : false;
                                       dictionary.Add(i, value);
                                   }
                                   resultList.Add(dictionary);
                               });
            return resultList;
        }
    }

使用示例

控制器:

        public ActionResult Index()
        {
            //example data
            var viewModel = new ViewModel
                                      {
                                          Columns = new List<Dictionary<int, bool>>
                                                        {
                                                            new Dictionary<int, bool> {{1, false}, {2, false}},
                                                            new Dictionary<int, bool> {{1, false}, {2, false}}
                                                        }
                                      };

            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Index(ViewModel viewModel)
        {
            //viewModel - contains values of user input
            return View();
        }

索引视图:

@model RepositoryTestProject.ViewModels.ViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>


@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>ViewModel</legend>


@Html.EditorFor(x => Model.Columns,"_ColumnEdit")

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

部分视图:(您应该在“/Views/Shared”中创建“EditorTemplates”文件夹并将部分模板放入文件夹)

_ColumnEdit局部视图:

@model List<Dictionary<int,bool>>

@for(int i =0; i < Model.Count();i++)
{
    @Html.EditorFor(x=>Model[i],"_DictEdit")
}

_DictEdit 局部视图:

@model Dictionary<int, bool>

@for(int i =0; i < Model.Count();i++)
{
    @Html.CheckBoxFor(x=>Model.ElementAt(i).Value)
}

需要在 global.asax 中注册您的模型绑定器

ModelBinders.Binders.Add(typeof(List<Dictionary<int,bool>>), new ListDictionaryModelBinder());

最后,您可以像这样在控制器中获取您的值:

在此处输入图像描述

于 2012-11-01T07:19:49.163 回答