7

これは、私が最近尋ねた別の質問に関連しています。ユーザー ロール情報をグリッドにバインドしようとしていて、ロールをユーザーに割り当てています。各ユーザーはデータベース内で複数の役割を持つことができ、これらは 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")

サーバーに送り返されたデータが空である明確な理由はありますか? 使用する正しいモデルを定義する MultiSelect コントロールから何かが欠けているのではないかと疑っています。同様の質問への回答としてよく引用されるテスト プロジェクトに言及しましたが、それも気に入りませんでした。

要求に応じて、(の要約版)私が使用しているコントローラー:

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

編集: サーバーにポストされたデータを表示すると、選択したオブジェクトの配列が正しく解析されていないように見えます。形式はRoleList[0].Id:123456である必要がありますが、代わりにRoleList[0][Id]:123456です。これは、私が書いたコードではなく、MultiSelect コントロールの問題であると考えていますか?

4

1 に答える 1

5

それで、私は最終的に問題が何であるかを理解しました。私の編集によると、データが MultiSelect コントロールから適切にシリアル化されていないことに気付きました。

Kendo の Web サイトで利用可能なサンプルを動作させるのにしばらく時間を費やしたところ、正しくシリアル化されたデータ正しくないデータがサーバーに投稿されていることに気付きました。彼らが使用したトリック (私にはばかげているように思えます) は、グリッドの Update 関数で、配列内のデータを自分でシリアル化することです。つまり、

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

「serialize」関数は次のように定義されています。

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

私の問題の解決策を広範囲に検索し、他の人が説明なしで有効な解決策を指摘されたので、Kendo で Kendo MultiSelect を使用しようとするときに、他の誰かが問題を理解するのに役立つかもしれないと思いました「この例を見てください」と言うだけでなく、グリッド。

tl;drサーバーに投稿する前に、常にKendo MultiSelect内のデータを自分でシリアル化してください(Kendo Gridを使用している場合)

于 2014-01-03T09:56:31.917 に答える