使用AJAX绑定时,创建/更新后,IEnumerable属性无法正确更新的Kendo Grid模型

时间:2022-01-08 01:19:46

I'm having a problem where a property of my model is not being correctly updated when sending it to my controller for an Update or Create call from a Kendo Grid. The model looks like this:

我遇到一个问题,当我将模型的属性发送到我的控制器以获取来自Kendo Grid的更新或创建调用时,我的模型的属性没有被正确更新。该模型如下所示:

public class ReleaseNotesModel
{
    public int NoteID { get; set; }
    public int ReleaseID { get; set; }
    public List<TranslationModel> ReleaseNoteTranslations { get; set; }
    public ReleaseNoteType ItemType { get; set; }
}
public class TranslationModel
{
    public int TranslationID { get; set; }
    public string Translation { get; set; }
    public int LanguageID { get; set; }
    public int ItemID { get; set; }
}

Here is the grid in my view:

这是我视图中的网格:

@(Html.Kendo().Grid<ReleaseNotesModel>()
    .Name("Grid")
    .Columns(columns =>
    {
        columns.Bound(m => m.ItemType).Width(140);
        columns.Bound(m => m.Description);
        columns.Command(command =>
            {
                command.Edit();
                command.Destroy();
            }).Width(170);
    })
    .ToolBar(toolbar => toolbar.Create())
    .Editable(editable => editable
        .Mode(GridEditMode.PopUp)
        .TemplateName("ReleaseNoteTemplate")
        .Window(w => w.Width(620))
        .DisplayDeleteConfirmation(true)
    )
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .DataSource(dataSource => dataSource
        .Ajax()
        .ServerOperation(false)
        //.Server()
        .Events(e => e.Error("grid_error"))
        .Model(model =>
        {
            model.Id(m => m.NoteID);
            model.Field(m => m.ReleaseID).DefaultValue(Model.ReleaseID);
            model.Field(m => m.ItemType).DefaultValue(ReleaseNoteType.NewFeature);
            //defaultTranslationsList is a List<TranslationModel> with two empty objects in it
            model.Field(m => m.ReleaseNoteTranslations).DefaultValue(defaultTranslationsList);
        })
        .PageSize(5)
        .Read(read => read.Action("GetNotes", "ReleaseNotes", new { releaseID = Model.ReleaseID }))
        .Create(create => create.Action("AddNote", "ReleaseNotes"))
        .Update(update => update.Action("EditNote", "ReleaseNotes"))
        .Destroy(destroy => destroy.Action("DeleteNote", "ReleaseNotes"))
    )
)

So more specifically, the problem I am having is that in my controller action:

更具体地说,我遇到的问题是在我的控制器操作中:

public async Task<ActionResult> EditNote(ReleaseNotesModel model)

model.ReleaseNoteTranslations always contains two empty objects (properties are null or 0), i.e. the default value which I set for this property. If I set no default value, then I won't have any fields to edit for this property in the popup editor. All the other properties are updated as expected.

model.ReleaseNoteTranslations总是包含两个空对象(属性为null或0),即我为此属性设置的默认值。如果我没有设置默认值,那么我将不会在弹出编辑器中为此属性编辑任何字段。所有其他属性都按预期更新。

What bugs me is that if I use server binding instead of AJAX, then all the data is correctly received. So I decided to check out the data in the request headers being sent in both cases:

让我感到困惑的是,如果我使用服务器绑定而不是AJAX,那么所有数据都会被正确接收。所以我决定检查两种情况下发送的请求标头中的数据:

// Using server binding
ReleaseID:300
NoteID:886
ItemType:1
ReleaseNoteTranslations[0].ItemID:886
ReleaseNoteTranslations[0].LanguageID:1
ReleaseNoteTranslations[0].TranslationID:869
ReleaseNoteTranslations[0].Translation:The module is now released!
ReleaseNoteTranslations[1].ItemID:886
ReleaseNoteTranslations[1].LanguageID:2
ReleaseNoteTranslations[1].TranslationID:870
ReleaseNoteTranslations[1].Translation:Le module est maintenant disponible!
NoteID:886

// Using AJAX binding
sort:
group:
filter:
NoteID:886
ReleaseID:300
ReleaseNoteTranslations[0][TranslationID]:869
ReleaseNoteTranslations[0][Translation]:The module is now released!
ReleaseNoteTranslations[0][LanguageID]:1
ReleaseNoteTranslations[0][ItemID]:886
ReleaseNoteTranslations[1][TranslationID]:870
ReleaseNoteTranslations[1][Translation]:Le module est maintenant disponible!
ReleaseNoteTranslations[1][LanguageID]:2
ReleaseNoteTranslations[1][ItemID]:886
ItemType:1

Now what I notice first here is the syntax of objectName[index].PropertyName vs objectName[index][PropertyName]

现在我首先注意的是objectName [index]的语法.PropertyName vs objectName [index] [PropertyName]

I wonder if this could be the cause of my problem, and if so, is there a way for me to go and directly manipulate the data being sent to fix it? Could this be a bug in the way Kendo Grid sends data through Ajax binding?

我想知道这是否可能是我的问题的原因,如果是这样,有没有办法让我去直接操纵发送的数据来修复它?这可能是Kendo Grid通过Ajax绑定发送数据的方式中的错误吗?

Either way, any help would be much appreciated!

无论哪种方式,任何帮助将不胜感激!

3 个解决方案

#1


14  

So In case anyone stumbles on this in the future, I contacted Telerik support, who explained to me that:

所以如果将来有人发现这个问题,我联系了Telerik的支持,他向我解释说:

The dataSource supports only value types and will not serialize the arrays in the format that is expected by the model binder.

dataSource仅支持值类型,不会以模型绑定程序所期望的格式序列化数组。

They also provided me with a workaround using the request Data function to call a JavaScript function which converts the data into the correct format.

他们还为我提供了一个解决方法,使用请求数据函数来调用JavaScript函数,该函数将数据转换为正确的格式。

In the view, modify the request functions by specifying the name of the JavaScript function to call:

在视图中,通过指定要调用的JavaScript函数的名称来修改请求函数:

.Create(create => create.Action("AddNote", "ReleaseNotes").Data("serialize"))

And then add in the functions which will do the conversion:

然后添加将进行转换的函数:

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++) {
        for (var property in array[i]) {
            result[prefix + "[" + i + "]." + property] = array[i][property];
        }
    }
}

#2


0  

Another issue could be that the kendo.aspnet.mvc.js is not included in the project. It appears to do the serialization trick when included.

另一个问题可能是kendo.aspnet.mvc.js未包含在项目中。它似乎在包含时进行序列化技巧。

#3


0  

Something that I noticed is that you need to add if condition as you don't need to serialize if the count is 1, just one item works fine without serialization

我注意到的一点是你需要添加if条件,因为你不需要序列化,如果计数是1,只有一个项目工作正常而没有序列化

#1


14  

So In case anyone stumbles on this in the future, I contacted Telerik support, who explained to me that:

所以如果将来有人发现这个问题,我联系了Telerik的支持,他向我解释说:

The dataSource supports only value types and will not serialize the arrays in the format that is expected by the model binder.

dataSource仅支持值类型,不会以模型绑定程序所期望的格式序列化数组。

They also provided me with a workaround using the request Data function to call a JavaScript function which converts the data into the correct format.

他们还为我提供了一个解决方法,使用请求数据函数来调用JavaScript函数,该函数将数据转换为正确的格式。

In the view, modify the request functions by specifying the name of the JavaScript function to call:

在视图中,通过指定要调用的JavaScript函数的名称来修改请求函数:

.Create(create => create.Action("AddNote", "ReleaseNotes").Data("serialize"))

And then add in the functions which will do the conversion:

然后添加将进行转换的函数:

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++) {
        for (var property in array[i]) {
            result[prefix + "[" + i + "]." + property] = array[i][property];
        }
    }
}

#2


0  

Another issue could be that the kendo.aspnet.mvc.js is not included in the project. It appears to do the serialization trick when included.

另一个问题可能是kendo.aspnet.mvc.js未包含在项目中。它似乎在包含时进行序列化技巧。

#3


0  

Something that I noticed is that you need to add if condition as you don't need to serialize if the count is 1, just one item works fine without serialization

我注意到的一点是你需要添加if条件,因为你不需要序列化,如果计数是1,只有一个项目工作正常而没有序列化