ASP.NET MVC CheckboxListFor值不回发

时间:2012-08-07 23:31:59

标签: asp.net-mvc-3 razor

绝望之下,我创建了一个CheckboxListFor方法,如下所示(我从某个地方扯掉了这个,可能在这里)。

public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TProperty>>> expression, MultiSelectList multiSelectList, object htmlAttributes = null)
        {
            //Derive property name for checkbox name
            var body = expression.Body as MemberExpression;
            string propertyName = body.Member.Name;

            //Get currently select values from the ViewData model
            IEnumerable<TProperty> list = expression.Compile().Invoke(htmlHelper.ViewData.Model);

            //Convert selected value list to a List<string> for easy manipulation
            var selectedValues = new List<string>();

            if (list != null)
            {
                selectedValues = new List<TProperty>(list).ConvertAll(i => i.ToString());
            }

            //Create div
            var divTag = new TagBuilder("div");
            divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);

            //Add checkboxes
            foreach (SelectListItem item in multiSelectList)
            {
                divTag.InnerHtml += String.Format("<div><input type=\"checkbox\" name=\"{0}\" id=\"{0}_{1}\" " +
                                                    "value=\"{1}\" {2} /><label for=\"{0}_{1}\">{3}</label></div>",
                                                    propertyName,
                                                    item.Value,
                                                    selectedValues.Contains(item.Value) ? "checked=\"checked\"" : "",
                                                    item.Text);
            }

            return MvcHtmlString.Create(divTag.ToString());
        }

我称之为:

 <h2>Rights</h2>
    <div>
        @Html.CheckBoxListFor(m=>m.SelectedRights, Model.Rights)
    </div>

它正确呈现出来。但是,所选值不会回发。我该如何解决这个问题?任何人都可以提出一个很好的起点吗?

更新 我认为添加更多细节可能会更好,因为这可能有多个问题。

复选框的ID显示为“SelectedRights_6”。 这是我目前正在使用的ViewModel。

 public class RoleSingleViewModel : BaseEntitySingleViewModel
    {
    public override int ListViewColSpan
    {
        get { return 6; }
    }

    public string Name {get;set;}
    public string Description {get;set;}

    public IEnumerable<SelectListItem> Sites {get;set;}
    public int SiteId{get;set;}
    public string SiteText{get;set;}
    public override string TypeName
    {
        get { return "Role"; }
    }

    public MultiSelectList Rights { get{return new MultiSelectList(AllRights, "Key", "Value", SelectedRights);}}
    public List<KeyValuePair<int, string>> AllRights { get; set; }
    public List<KeyValuePair<int, string>> SelectedRights { get; set; }
}

此外,控制器上的更新方法是这样的。我在抛出异常的行上设置了一个断点,并检查了updateItem。不填写Rights,AllRights和SelectedRights的值(我猜,这是预期的行为)。我在想我的问题可能与我的ViewModel的结构有关。我该怎么改变它?

[HttpPost]
public ActionResult Edit(RoleSingleViewModel updateItem)
    {
      throw new NotImplementedException();

    }

2 个答案:

答案 0 :(得分:0)

从复选框中删除 ID属性。当它向服务器发布选定值(仅)时,它将是整数或字符串数​​组(我从未使用字符串测试过)。所以你的模型/参数应该具有相同的属性名称(,它应该是一个数组)。

答案 1 :(得分:0)

我发现我需要初始化一个集合以便绑定结果,即必须在绑定之前初始化For属性。模型绑定器不会创建集合,但如果已经定义了集合,它将添加项目:

在你的模特上

private IEnumerable<int> checkedItems = new List<int>();

public IEnumerable<int> CheckedItems
{ 
    get { 
        return this.checkedItems ;
    }

    set {
        this.checkedItems  = value;
    }
}

在剃刀视图中

@Html.CheckBoxListFor(CheckedItems, ...)