2011-01-27 18 views
9

Sto avendo una classe come segueselezioni multiple CheckBoxList: difficoltà nel modello legano indietro

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

e public UserRoleModel[] UserRoles { get; set; }


mio controller è la seguente:

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

    [HttpPost] 
    public ActionResult CreateUser(UserDetailsModel model) 
    { 

     return View(model); 
    } 

Dal mio punto di vista sto avendo

>@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> 
    } 

Nonostante i valori visualizzati di conseguenza, secondo la mia vista, non esiste alcun vincolo di modello per UserRoles. Cosa mi manca o esiste un metodo migliore e più pulito?

risposta

21

Questo tipo di cose sono ben realizzate con i modelli di editor. Inoltre ti evitano di scrivere codice spaghetti nelle tue opinioni. Esempio:

Modello:

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

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

Controller:

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); 
    } 
} 

View (~/Views/Home/Index.cshtml):

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

editor di modelli (~/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) 

Questo è ciò che chiamo roba pulita.

+0

Una cosa che non ho notato fino a quando non l'ho provata in realtà - il @ Html.EditorFor (x => x.Roles) effettivamente eseguirà l'iterazione attraverso la raccolta. Pulito davvero. – chris

+0

Grande. Questa sembra una buona soluzione per quello che sto cercando (finalmente). Sicuramente lo proverò domani. Non riuscivo a trovare qualcosa che mi soddisfacesse anche su HttpPost; probabilmente stava cercando la cosa sbagliata. La maggior parte delle soluzioni richiedeva un array o un altro parametro aggiuntivo nell'azione HttpPost del controller. Grazie, Darin. – Rodi

+1

Testato ora e funziona anche per la mia situazione. Ma ho modificato 'LabelFor' per usare la stessa proprietà di' CheckBoxFor' in modo che facendo clic sull'etichetta si attiva anche la casella di controllo. In questo esempio sarebbe: '@ Html.LabelFor (x => x.UserRole, Model.Role)' – Rodi

Problemi correlati