2013-12-18 10 views
5

Questo è relativo a another question I asked di recente. Sto cercando di associare le informazioni sui ruoli utente a una griglia e assegno i ruoli a un utente. Ogni utente può essere in più ruoli all'interno del database e questi devono essere modificati utilizzando un'interfaccia utente Kendo MultiSelect.Utilizzo di Kendo MultiSelect con griglia UI di Kendo in ASP.NET MVC

Quando seleziono i ruoli richiesti e ritorna al controller, la matrice di oggetti "RoleBasicModel" contiene il numero richiesto di ruoli, ma tutte le loro proprietà sono vuote.

I modelli sono definiti come:

public class UserInfo 
{ 
    public string UserId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string UserName { get; set; } 
    public string Roles { get; set; } 
    public IEnumerable<RoleBasicModel> RoleList { get; set; } 
} 
public class RoleBasicModel 
{ 
    public string Id { get; set; } 
    public string Text { get; set; } 
} 

La griglia è configurato come:

@(Html.Kendo().Grid<Models.UserInfo>() 
    .Name("userGrid") 
    .Columns(columns => 
    { 
     columns.Bound(p => p.UserName); 
     columns.Bound(p => p.FirstName); 
     columns.Bound(p => p.LastName); 
     columns.Bound(p => p.Roles).EditorTemplateName("RoleListEditor").Template(p => p.RoleList); 
     columns.Command(command => { command.Edit(); command.Destroy(); }); 
    }) 
    .Filterable() 
    .Sortable() 
    .Resizable(r => r.Columns(true)) 
    .Editable(editable => { editable.Mode(GridEditMode.InLine); editable.DisplayDeleteConfirmation("Are you sure you want to remove this user?"); }) 
    .HtmlAttributes(new { style = "min-height:90px;max-height:450px;" }) 
    .DataSource(dataSource => dataSource 
     .Ajax() 
     .Events(events => events.Error("error_handler")) 
     .Model(model => 
     { 
      model.Id(p => p.UserId); 
      model.Field(p => p.UserId).Editable(false); 
      model.Field(p => p.FirstName).Editable(true); 
      model.Field(p => p.LastName).Editable(true); 
      model.Field(p => p.UserName).Editable(false); 
      model.Field(p => p.RoleList).Editable(true); 
     } 
     ).Read(read => read.Action("GetAllUsers", "Admin").Type(HttpVerbs.Get)) 
     .Update(update => update.Action("UpdateUser", "Admin").Type(HttpVerbs.Post)) 
     .Destroy(update => update.Action("DeleteUser", "Admin").Type(HttpVerbs.Post)) 
    ) 
) 

E il mio editor di modelli, che utilizza il Kendo multipla, è definito come:

@Html.Kendo().MultiSelect().Name("RoleList").DataTextField("Text").DataValueField("Id").BindTo((IEnumerable<Models.RoleBasicModel>)ViewData["uroles"]).Placeholder("No role selected") 

C'è qualche ragione ovvia per cui i dati inviati al server sono vuoti? Sospetto che mi manchi qualcosa del controllo MultiSelect che definirà il modello corretto da utilizzare. Ho fatto riferimento a the test project che è spesso citato come risposta a domande simili, ma non ho avuto nemmeno gioia con quello.

Come richiesto, (una versione ridotta) del controllore che sto utilizzando:

public ActionResult ManageUsers() 
    {    
     PopulateRoles(); 
     return View(); 
    } 

    private void PopulateRoles() 
    { 
     ViewData["uroles"] = new ApplicationDbContext().Roles.Select(r => new RoleBasicModel { Text = r.Name, Id = r.Id }).ToList(); 
    } 

    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult GetAllUsers([DataSourceRequest]DataSourceRequest request) 
    { 
     using (var context = new ApplicationDbContext()) 
     { 
      var allUsers = context.Users.ToList().Select(x => 
       new UserInfo 
       { 
        UserName = x.UserName, 
        UserId = x.Id, 
        FirstName = x.FirstName, 
        LastName = x.LastName, 
        RoleList = x.Roles.Select(p => new RoleBasicModel { Text = p.Role.Name, Id = p.RoleId }), 
        Roles = string.Join(", ", x.Roles.Select(p => p.Role.Name).ToList()) 
       }).ToList(); 
      return Json(allUsers.ToDataSourceResult(request), JsonRequestBehavior.AllowGet); 
     } 
    } 

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult UpdateUser([DataSourceRequest] DataSourceRequest request, UserInfo user) 
    { 
     if (user != null && ModelState.IsValid) 
     { 
      using (var context = new ApplicationDbContext()) 
      { 
// Do something with the user details 
      } 
     } 

     return Json(new[] { user }.ToDataSourceResult(request, ModelState)); 
    } 

EDIT: Su visualizzazione dei dati pubblicati al server, sembra come se la serie di oggetti selezionati isn' Ho analizzato correttamente. Il formato deve essere RoleList [0] .ID: 123456 ma è invece RoleList [0] [Id]: 123456. Sto pensando che questo potrebbe essere un problema con il controllo MultiSelect, piuttosto che qualsiasi codice che ho scritto?

+0

Perché si postare così in fretta su qualcosa che, ovviamente, non era completa ? Dacci idioti una pausa!:) – loxdog

+0

Potrei porre la stessa domanda a te, perché pubblicare qualcosa che ovviamente non era completo? – tnw

+0

Ingresso accidentalmente premuto! Un errore onesto che sono riuscito a fare prima su Stack ... – loxdog

risposta

4

Quindi alla fine ho capito qual era il problema. Come da mia modifica, ho notato che i dati non erano serializzati correttamente dal controllo MultiSelect.

Ho trascorso un po 'di tempo a far funzionare il example available on the Kendo website e ho notato che hanno postato i dati serializzati correttamente e in modo errato sul server. Il trucco hanno usato (che sembra ridicolo me) è che la funzione di aggiornamento sulla griglia, che serializzare i dati all'interno di un array per sé ie

.Update(update => update.Action("UpdateUser", "Admin").Type(HttpVerbs.Post).Data("serialize"))

Qualora la funzione "serializzare" è definito come:

function serialize(data) { 
    for (var property in data) { 
     if ($.isArray(data[property])) { 
      serializeArray(property, data[property], data); 
     } 
    } 
} 

function serializeArray(prefix, array, result) { 
    for (var i = 0; i < array.length; i++) { 
     if ($.isPlainObject(array[i])) { 
      for (var property in array[i]) { 
       result[prefix + "[" + i + "]." + property] = array[i][property]; 
      } 
     } 
     else { 
      result[prefix + "[" + i + "]"] = array[i]; 
     } 
    } 
} 

aver cercato in giro ampiamente di risoluzione al mio problema, e le altre persone sono state fatte notare per una soluzione di lavoro senza spiegazioni, ho pensato che potrebbe essere utile a qualcun altro per capire qual è il problema quando si tenta di usa un Kendo MultiSelect in una Kendo Grid, piuttosto che solo sayin g "guarda questo esempio".

tl; dr puntate sempre i dati all'interno di un Kendo multipla te stesso prima di inviare al server (se si sta utilizzando un Kendo Grid)

+0

Grazie mille per aver postato questa risposta. Penso che questo sia esattamente quello che sto cercando. – madvora