2011-01-27 7 views
9

CheckBoxListの複数選択:モデルバインドの難しバック

public class UserRoleModel 
{ 
    public string Role { get; set; } 
    public bool UserRole { get; set; } 
} 

public UserRoleModel[] UserRoles { get; set; }


次のように私のコントローラである次のように私はクラスを持っています:

public ActionResult CreateUser() 
    { 
     UserDetailsModel model = new UserDetailsModel(); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult CreateUser(UserDetailsModel model) 
    { 

     return View(model); 
    } 

私の見解では、私は

>@foreach (var item in Model.UserRoles)  
    { 

    name = "UserRoles"+ ".Value["+ i + "]"; 
    id= "UserRoles" + "_Value[" + i++ + "]"; 
    selected = item.UserRole ? "checked=\"checked\"" : ""; 

     <p> 
     <input type="checkbox" name="@name" id="@id" @selected value="true" /> 
     <label for="@id">@item.Role</label> 
     <input type="hidden" name="@name" value="false" /> 
     </p> 
    } 

私の見解に応じて値が表示されていますが、UserRolesのモデルバインドバックはありません。私は何が欠けているのですか、より良い、よりクリーンな方法がありますか?

答えて

21

これらの種類のものは、エディタテンプレートでうまくいきます。彼らはまたあなたの意見にスパゲティコードを書くのを避けます。例:

モデル:

public class UserDetailsModel 
{ 
    public IEnumerable<UserRoleModel> Roles { get; set; } 
} 

public class UserRoleModel 
{ 
    public string Role { get; set; } 
    public bool UserRole { get; set; } 
} 

コントローラー:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new UserDetailsModel 
     { 
      // Fill with some dummy stuff 
      Roles = Enumerable.Range(1, 5).Select(x => new UserRoleModel 
      { 
       Role = "role " + x, 
       UserRole = false 
      }) 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(UserDetailsModel model) 
    { 
     return View(model); 
    } 
} 

ビュー(~/Views/Home/Index.cshtml):

@model AppName.Models.UserDetailsModel 
@using (Html.BeginForm()) 
{ 
    @Html.EditorFor(x => x.Roles) 
    <input type="submit" value="OK" /> 
} 

エディタのテンプレート(~/Views/Home/EditorTemplates/UserRoleModel.cshtml):

@model AppName.Models.UserRoleModel 
@Html.CheckBoxFor(x => x.UserRole) 
@Html.LabelFor(x => x.Role, Model.Role) 
@Html.HiddenFor(x => x.Role) 

ここで私はクリーンなものと呼んでいます。

+0

@ Html.EditorFor(x => x.Roles)は、実際にコレクションを繰り返し処理するまで気付かなかったことがあります。本当にきれい。 – chris

+0

これは、私が探しているもの(最終的には)のための素晴らしいソリューションのように見えます。明日明日にそれを試してみましょう。私はHttpPostでバインドされた内容のコンテンツを見つけることができませんでした。おそらく間違ったことを探していたでしょう。ほとんどのソリューションでは、コントローラーのHttpPostアクションに追加の配列やその他のパラメーターが必要でした。ありがとうダーリン。 – Rodi

+1

これをテストしたところ、私の状況でも動作します。しかし、私は 'LabelBox'を' CheckBoxFor'と同じプロパティーを使用するように変更し、ラベルをクリックするとチェックボックスもトリガーされるようにしました。この例では、次のようになります。 '@Html.LabelFor(x => x.UserRole、Model.Role)' – Rodi