Использование Kendo MultiSelect с сеткой Kendo UI в ASP.NET MVC
Это связано с другим вопросом, который я недавно задал. Я пытаюсь привязать информацию о роли пользователя к сетке и назначаю роли пользователю. Каждый пользователь может быть в нескольких ролях в базе данных, и они должны быть отредактированы с помощью Kendo UI MultiSelect.
Когда я выбираю требуемые роли и отправляю их обратно в контроллер, массив объектов "RoleBasicModel" содержит необходимое количество ролей, но все их свойства пусты.
Модели являются определяется как:
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; }
}
Сетка настраивается следующим образом:
@(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))
)
)
И мой шаблон редактора, который использует Kendo MultiSelect, определяется следующим образом:
@Html.Kendo().MultiSelect().Name("RoleList").DataTextField("Text").DataValueField("Id").BindTo((IEnumerable<Models.RoleBasicModel>)ViewData["uroles"]).Placeholder("No role selected")
Есть ли какая-либо очевидная причина, по которой данные, отправленные обратно на сервер, пусты? Я подозреваю, что мне не хватает чего-то из Мультиселектного элемента управления, который определит правильную модель для использования. Я ссылался натестовый проект , который часто цитируется в качестве ответа на подобные вопросы, но и это меня не радовало.
Как запрошен (сокращенная версия) контроллер, который я использую:
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: при просмотре данных, отправленных обратно на сервер, создается впечатление, что массив выбранных объектов не был правильно проанализирован. Формат должен быть RoleList[0]. Id:123456, но вместо этого RoleList[0] [Id]: 123456. Я думаю, что это может быть проблемой с управлением MultiSelect, а не с любым написанным мной кодом?
1 ответ:
Так что в конце концов я понял, в чем была проблема. Согласно моему редактированию, я заметил, что данные не были сериализованы должным образом из элемента управления MultiSelect.
Я потратил некоторое время на то, чтобы пример , доступный на веб-сайте Kendo, работал, и я заметил, что они разместили данные, сериализованные правильно и неправильно на сервер. Трюк, который они использовали (что кажется мне смешным), заключается в том, что в функции обновления сетки они сериализуют любые данные внутри массива для сами т. е.
.Update(update => update.Action("UpdateUser", "Admin").Type(HttpVerbs.Post).Data("serialize"))Где функция "serialize" определяется как:
Я долго искал решение своей проблемы, и другие люди указывали на рабочее решение без объяснения причин, я подумал, что это может быть полезно для кого-то еще, чтобы понять, в чем проблема, когда вы пытаетесь использовать Kendo MultiSelect в сетке Kendo, а не просто сказать: "посмотрите на этот пример".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]; } } }Tl; dr Всегда сериализуйте данные внутри a Kendo MultiSelect yourself before posting to the server (если вы используете сетку Kendo)
Comments