如何在复杂的ViewModel中绑定IDictionary?

时间:2014-06-08 09:42:56

标签: c# asp.net-mvc dictionary model-binding

我有一个带有字典字段的复杂viewModel。

public class FieldViewModel
    {
        public int Id { get; set; }

        public int Type { get; set; }

        public string Name { get; set; }

        public string Additional { get; set; }

        public Dictionary<string, string> Options = new Dictionary<string, string>(); 

        public ViewState ViewState = ViewState.Save;

        public IList<SelectListItem> Types = new List<SelectListItem>();

        public static FieldViewModel BuildFieldVIewModel(Field fieldEntity = null)
        {
            FieldViewModel viewModel = new FieldViewModel();
            viewModel.Options.Add("key1","val1"); //just for test
            viewModel.Options.Add("key2","val2");
            if (fieldEntity != null)
            {
                viewModel.Id = fieldEntity.Id;
                viewModel.Type = fieldEntity.Type;
                viewModel.Name = fieldEntity.Name;
                viewModel.Additional = fieldEntity.Additinal;
                viewModel.ViewState = ViewState.Edit;
            }

            viewModel.Types = Enum.GetValues(typeof(FieldType)).Cast<FieldType>().Select(x => new SelectListItem {
            Value = ((int)x).ToString(CultureInfo.InvariantCulture),
            Text = Enum.GetName(typeof(FieldType), x),
            Selected = fieldEntity != null && ((int)x) == fieldEntity.Id
            }).ToList();

            return viewModel;
        }
    }

Razor观点

@using (Html.BeginForm("Save", "Dictionary", FormMethod.Post))
{
    var index = 0;
    @Html.HiddenFor(m => m.FieldId);
    foreach (KeyValuePair<string, string> kv in Model.Options)
    {
        <div class="row">
            <div class="col-md-2">
           <input type="text" name="@string.Format("Options[{0}].Key", index)" value="@kv.Key" />
        </div>
        <div class="col-md-2">
            <input type="text" name="@string.Format("Options[{0}].Value", index)" value="@kv.Value" />
        </div>            </div>
        index++;
    }
    <input type="submit" value="Save" />
}

渲染的html是

<form action="/Dictionary/1/Save" method="post"><input data-val="true" data-val-number="The field FieldId must be a number." data-val-required="The FieldId field is required." id="FieldId" name="FieldId" type="hidden" value="1">        <div class="row">
            <div class="col-md-2">
               <input type="text" name="Options[0].Key" value="key1">
            </div>
            <div class="col-md-2">
                <input type="text" name="Options[0].Value" value="val1">
            </div>
        </div>
        <div class="row">
            <div class="col-md-2">
               <input type="text" name="Options[1].Key" value="key2">
            </div>
            <div class="col-md-2">
                <input type="text" name="Options[1].Value" value="val2">
            </div>
        </div>
    <input type="submit" value="Save">
</form>

但是在行动方法中,我的字典是空的。

[HttpPost]
public ActionResult Save(FieldViewModel viewModel)
{
    if (viewModel.Options.Count == 0)
    {
        throw new Exception("Dictionary is empty.");
    }
    return RedirectToAction("Index", new { fieldId = 1 });
}

我必须使用哪个名称来正确地在viewModel中绑定字典的输入?

1 个答案:

答案 0 :(得分:2)

更改

public Dictionary<string, string> Options = new Dictionary<string, string>();

public Dictionary<string, string> Options {get;set;}

并添加

Options = new Dictionary<string, string>(); 

进入你的构造函数。