2013-12-18 16 views
5

Dies ist verwandt mit another question I asked über vor kurzem. Ich versuche, Benutzerrolleninformationen an ein Raster zu binden, und ich weise einem Benutzer Rollen zu. Jeder Benutzer kann mehrere Rollen in der Datenbank haben, und diese sollten mit einem Kendo UI MultiSelect bearbeitet werden.Verwenden von Kendo MultiSelect mit Kendo UI-Grid in ASP.NET MVC

Wenn ich die erforderlichen Rollen auswähle und an den Controller zurückmelde, enthält das Array der "RolebasicModel" -Objekte die erforderliche Anzahl an Rollen, aber alle ihre Eigenschaften sind leer.

Die Modelle wie definiert sind:

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

Das Raster ist Setup als:

@(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)) 
    ) 
) 

Und mein Editor-Vorlage, die die Kendo Multiselect verwendet, wie folgt definiert ist:

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

Gibt es einen offensichtlichen Grund, warum die zum Server gesendeten Daten leer sind? Ich vermute, dass etwas vom MultiSelect-Steuerelement fehlt, das das richtige Modell definiert. Ich habe mich auf the test project bezogen, das oft als Antwort auf ähnliche Fragen zitiert wird, aber ich hatte auch keine Freude damit.

Wie gewünscht, (eine gekürzte Version) die Steuerung Ich verwende:

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: Nach der Anzeige von Daten an den Server zurück, scheint es, als ob das Array von ausgewählten Objekten ‚isn t richtig geparst. Das Format sollte RoleList [0] .Id: 123456 sein, ist aber stattdessen RoleList [0] [Id]: 123456. Ich denke, dass dies ein Problem mit dem MultiSelect-Steuerelement sein könnte und nicht irgendein Code, den ich geschrieben habe?

+0

Warum würden Sie so schnell auf etwas posten, die offensichtlich nicht vollständig war ? Gib uns Idioten eine Pause!:) – loxdog

+0

Ich könnte dir die gleiche Frage stellen, warum posten Sie sogar etwas, das offensichtlich nicht vollständig war? – tnw

+0

Versehentlich gedrückt drücken! Ein ehrlicher Fehler, den ich vorher auf Stack gemacht habe ... – loxdog

Antwort

4

Also habe ich schließlich herausgefunden, was das Problem war. Laut meiner Bearbeitung habe ich festgestellt, dass die Daten nicht ordnungsgemäß vom MultiSelect-Steuerelement serialisiert wurden.

Ich habe einige Zeit damit verbracht, die example available on the Kendo website funktioniert und ich bemerkte, dass sie die Daten korrekt serialisiert und falsch an den Server. Der Trick, den sie benutzt (was mir lächerlich scheint) ist, dass auf der Update-Funktion auf dem Gitter, sie alle Daten innerhalb eines Arrays serialise für sich selbst, dh

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

Wo die „serialize“ Funktion ist definiert als:

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

um ausgiebig für eine Auflösung zu meinem Problem gesucht hat, und andere Menschen zu einer Arbeitslösung ohne Erklärung hingewiesen worden, dachte ich, es könnte jemand anderes nützlich sein, zu verstehen, was das Problem ist, wenn Sie versuchen, Verwenden Sie einen Kendo MultiSelect in einem Kendo-Grid, anstatt nur zu sagen g "Schau dir dieses Beispiel an".

tl; dr serialise immer die Daten in einem Kendo Multiselect sich vor dem Server veröffentlichen (wenn Sie einen Kendo Grid verwenden)

+0

Vielen Dank für das Posten dieser Antwort. Ich denke, das ist genau das, wonach ich suche. – madvora

Verwandte Themen