我目前正在使用 Web API v2 和 OData v3 链接到 Kendo Grid。我在让网格正确地将模型序列化为类上的PatchEntityAsync
方法时遇到问题。传递给方法的显然是不正确的。AsyncEntitySetController<TEntity, TKey>
Delta<TEntity>
PatchEntityAsync
null
首先,实体框架模型。我有一个GameSeries
定义:
[Table("stats.GameSeries")]
public class GameSeries
{
[Key]
public int GameSeriesId { get; set; }
[MaxLength(500)]
[Required]
public string Description { get; set; }
public string Notes { get; set; }
}
然后是Game
定义,每个Game
实例都有一个实例的引用GameSeries
:
[Table("stats.Game")]
public class Game
{
[Key]
public int GameId { get; set; }
[MaxLength(500)]
[Required]
public string Description { get; set; }
public int GameSeriesId { get; set; }
[ForeignKey("GameSeriesId")]
public virtual GameSeries GameSeries { get; set; }
public int Revision { get; set; }
[MaxLength(100)]
public string Tag { get; set; }
public string Notes { get; set; }
}
查询使用 JSON 并在属性上Game
发出一个时,我得到以下内容,这是预期/正确的:$expand
GameSeries
{
"odata.metadata":
"http://localhost:7566/odata/$metadata#Games",
"odata.count":"58",
"value":[
{
"GameSeries": {
"GameSeriesId": 1,
"Description":"Street Fighter IV",
"Notes":null
},
"GameId": 1,
"Description": "Street Fighter IV",
"GameSeriesId": 1,
"Revision": 1,
"Tag": null,
"Notes": null
}, {
"GameSeries": {
"GameSeriesId":1,
"Description": "Street Fighter IV",
"Notes": null
},
"GameId": 2,
"Description": "Super Street Fighter IV",
"GameSeriesId": 1,
"Revision": 2,
"Tag": null,
"Notes": null
},
// And so on...
]
}
我通过 OData Web API (Microsoft.AspNet.WebApi.OData 5.2.0) 端点将这些暴露给 Kendo UI Grid。这是网格的配置:
function initializeGrid(selector, entitySet, key, modelFields, columns, expand) {
// Edit and destroy commands.
columns.push({ command: ["edit", "destroy"], title: "Operations" });
// The main key is not editable.
modelFields[key].editable = false;
modelFields[key].defaultValue = 0;
var baseODataUrl = "/odata/" + entitySet,
options = {
dataSource: {
type: "odata",
pageSize: 50,
//autoSync: true,
transport: {
read: {
url: baseODataUrl,
dataType: "json",
data: {
$expand: expand
}
},
update: {
url: function(data) {
return baseODataUrl + "(" + data[key] + ")";
},
type: "patch",
dataType: "json"
},
destroy: {
url: function (data) {
return baseODataUrl + "(" + data[key] + ")";
},
dataType: "json"
},
create: {
url: baseODataUrl,
dataType: "json",
contentType: "application/json;odata=verbose"
}
},
batch: false,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
schema: {
data: function (data) {
return data.value;
},
total: function (data) {
return data["odata.count"];
},
model: {
id: key,
fields: modelFields
}
}
},
height: 550,
toolbar: ["create"],
filterable: true,
sortable: true,
pageable: true,
editable: "popup",
navigatable: true,
columns: columns
};
selector.kendoGrid(options);
}
$(function () {
var baseODataUrl = "/odata/",
gameSeriesIdDataSource = new kendo.data.DataSource({
type: "odata",
schema: {
data: function (data) {
return data.value;
},
total: function (data) {
return data["odata.count"];
}
},
transport: {
read: {
url: baseODataUrl + "GameSeries",
dataType: "json"
}
}
}),
gameSeriesIdAutoCompleteEditor = function(container, options) {
$('<input data-text-field="Description" data-value-field="GameSeriesId" data-bind="value:GameSeriesId"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: gameSeriesIdDataSource,
dataTextField: "Description",
dataValueField: "GameSeriesId"
});
};
initializeGrid($("#grid"), "Games", "GameId", {
GameId: {
title: "Game ID",
editable: false
},
Description: { type: "string" },
GameSeriesId: { type: "integer" },
Revision: { type: "integer" },
Tag: { type: "string" },
Notes: { type: "string" }
}, [
{ field: "GameId", title: "Game ID" },
"Description",
{ field: "GameSeries.Description", title: "Game Series", editor: gameSeriesIdAutoCompleteEditor },
"Revision",
"Tag",
"Notes"
], "GameSeries");
});
}(jQuery));
这将正确呈现网格,我将在其中GameSeries.Description
显示而不是GameSeries
.
但是,我相信部分问题来自我如何定义自定义编辑器,特别data
是 Kendo 所需的属性:
$('<input data-text-field="Description" data-value-field="GameSeriesId" data-bind="value:GameSeriesId"/>')
我觉得我应该使用点符号来引用实例GameSeries
上的属性Game
,但我不确定如何。
此外,我相信这里的绑定导致 create 命令失败。应该有一些方法来设置数据绑定属性,这将允许新的创建,以及编辑现有的。
但是,当我让编辑器为现有实例弹出时,它会正确地使用填充了所有实例的下拉列表GameSeries
。
我可以进行更改,当我这样做时,我通过 Fiddler 注意到身体正在通过,尽管我注意到一些差异:
{
"GameSeries": {
"GameSeriesId": 1,
"Description": "Street Fighter IV",
"Notes": null
},
"GameId": "1",
"Description":
"Street Fighter IV",
"GameSeriesId": "4",
"Revision": "1",
"Tag": "Test",
"Notes": null
}
在这种情况下,GameSeriesId
属性正确填充了更改(我想要4),但扩展GameSeries
属性的“GameSeriesId”为 1。
进行此调用时,Delta<Game>
传入的实例为空。
我试过的:
我注意到GameSeriesId
扩展GameSeries
属性上的属性没有被字符串化。我已将值更改为"1"
" 并且Delta<Game>
实例仍然为空。
我已复制对 OData 点的调用以不包含扩展GameSeries
属性,因此有效负载如下所示:
{
"GameId": "1",
"Description":
"Street Fighter IV",
"GameSeriesId": "4",
"Revision": "1",
"Tag": "Test",
"Notes": null
}
并且Delta<Game>
人口众多。我不确定GameSeries
从有效负载中删除扩展属性是否是正确的方法,或者是否应该在服务器端或剑道网格中解决它。