2012-08-07 31 views
0

无奈之下,我创建了一个CheckboxListFor方法,如下所示(我在某处可能会在此处将其撕掉)。ASP.NET MVC 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(); 

    } 
+0

好,首先查看浏览器中呈现的HTML并查看正在呈现的控件的名称。然后使用fiddler或代码检查发布的值,看看是否有这些值。如果他们是,那么你的问题可能是命名约定不匹配。你怎么知道价值没有被张贴?发布接收这些值的控制器代码。 – 2012-08-08 00:35:35

+0

该ID看起来像“SelectedRights_6”。 – 2012-08-11 21:45:45

回答

0

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

0

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

在你的模型

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

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

    set { 
     this.checkedItems = value; 
    } 
} 

而在Razor视图

@Html.CheckBoxListFor(CheckedItems, ...)