2011-12-22 4 views
9

でのviewmodelにチェックボックスをバインドすることができます:コントローラでは、どのように私は本当にこのまわりで私の頭を包むのに苦労していmvc3

public class UserModel 
{ 
    [Required] 
    [Display(Name = "User name")] 
    public string UserName { get; set; } 

    [Required] 
    [DataType(DataType.EmailAddress)] 
    [Display(Name = "Email address")] 
    public string Email { get; set; } 

    [Required] 
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [DataType(DataType.Password)] 
    [Display(Name = "Confirm password")] 
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; } 

    public IEnumerable<string> UserRoles { get; set; } 
} 
public class UserRoleModel 
{ 
    public IEnumerable<string> AllRoles { get; set; } 
    public UserModel user { get; set; } 

    public UserRoleModel() 
    { 
     this.AllRoles = Roles.GetAllRoles(); 
     this.user = new UserModel(); 
    } 
} 

は、私がUserModelとUserRoleModelを持っている

 public ActionResult Create() 
    { 
     return View(new UserRoleModel()); 
    } 

    [HttpPost] 
    public ActionResult Create(UserRoleModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      MembershipCreateStatus createStatus; 
      Membership.CreateUser(model.user.UserName, model.user.Password, model.user.Email, null, null, true, null, out createStatus); 

      if (createStatus == MembershipCreateStatus.Success) 
      { 
       foreach (var r in model.AllRoles) 
       { 
        Roles.AddUserToRole(model.user.UserName, r); 
       } 

       return RedirectToAction("Index", "Home"); 
      } 
      else 
      { 
       ModelState.AddModelError("", ErrorCodeToString(createStatus)); 
      } 
     } 

     return View(model); 
    } 

とビュー:

@model BBmvc.Areas.Tools.Models.UserRoleModel 

と:

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

    <div class="editor-label"> 
     @Html.LabelFor(model => model.user.UserName) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.user.UserName) 
     @Html.ValidationMessageFor(model => model.user.UserName) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.user.Email) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.user.Email) 
     @Html.ValidationMessageFor(model => model.user.Email) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.user.Password) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.user.Password) 
     @Html.ValidationMessageFor(model => model.user.Password) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.user.ConfirmPassword) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.user.ConfirmPassword) 
     @Html.ValidationMessageFor(model => model.user.ConfirmPassword) 
    </div> 
    <div class="editor-field"> 
     @foreach (var r in @Model.AllRoles) 
     { 
      @Html.CheckBox(r,false) 
      @Html.Label(r) 
      <br /> 
     } 
    </div> 

    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 

}

まず、私は私のViewModelからCheckBoxForを使用する方法を見つけ出すことができませんでした。しかし、それはチェックボックスのオプションを表示するので、私はそれと一緒に暮らすことができます。しかし、フォームの投稿時にどのチェックボックスがチェックされているかを判断する方法はわかりません。私はまた、クライアント側の検証を壊しているように見える、私はviewModelを使用していると仮定します。

答えて

13

CheckBoxForヘルパーは、ブール値のプロパティで動作します。だから、ビューモデルを定義できます。

public class RoleViewModel 
{ 
    public string Name { get; set; } 
    public bool Selected { get; set; } 
} 

をして、あなたのビューモデルにAllRolesプロパティを変更:

public class UserRoleModel 
{ 
    public IEnumerable<RoleViewModel> AllRoles { get; set; } 
    public UserModel user { get; set; } 

    public UserRoleModel() 
    { 
     this.AllRoles = Roles.GetAllRoles().Select(r => new RoleViewModel 
     { 
      Name = r 
     }); 
     this.user = new UserModel(); 
    } 
} 

とビューではなく、foreachループを書くには、エディタのテンプレートを使用します

<div class="editor-field"> 
    @Html.EditorFor(x => x.AllRoles) 
</div> 

最後に、の各要素に対して自動的にレンダリングされるRoleViewModelタイプのエディタテンプレートを定義します210コレクション(~/Views/Shared/EditorTemplates/RoleViewModel.cshtml

@model RoleViewModel 
@Html.CheckBoxFor(x => x.Selected) 
@Html.LabelFor(x => x.Selected, Model.Name) 
@Html.HiddenFor(x => x.Name) 
<br /> 

これだけです。投稿アクションの中で、AllRolesプロパティに値が入力されます。

+1

チェックボックスがチェックされているかどうかに関係なく、ポストアクションでは、AllRoles.Selectedプロパティは常にfalseに設定されます。 – Rob

0

前の回答でRobが指摘したように、すべてのSelectedプロパティはFalseです。 私はこれをカバーするためにこのコードを使用しました。

AllRoles = Roles.GetAllRoles().Select(r => new RoleViewModel() 
{ 
    Name = r, 
    Selected = Roles.GetRolesForUser(uvm.UserProfile.UserName).Contains(r) ? true : false 
}); 
関連する問題