AngularJSとKendoUIを使用してグリッドを作成しています。グリッドは、WebAPI Webサービスからデータを取得します。グリッドについては、サーバー側のソート、ページング、フィルタリング、およびグループ化を許可したいと思います。この目的のために、 KendoGridBinderExライブラリを使用しようとしています。
KendoGridBinderExソースをダウンロードし、サンプルプロジェクトを実行しましたが、問題なく動作します。ただし、プロジェクトでまったく同じことを行うと、グリッドの列でフィルターを実行しようとすると、次のエラーが発生します。
System.Linq.Dynamic.ParseException:タイプ 'MyEntity'にプロパティまたはフィールド 'test'が存在しません
「テスト」はフィルターに入力するものなので、フィルターテキストにする必要があります。 「test」というプロパティまたはフィールドを探すべきではありません。
私はFiddlerをデバッグして使用し、リクエストで送信されるリクエストのフィルター部分が例の作業中のリクエストとまったく同じであることを確認したので、問題はリクエスト側にあるとは思いません。
すべてのコードブロックについて、スペースを節約し、関連のないものを切り取るためにすべてを簡略化しています。たとえば、データベースコードを切り取って、オンザフライでエンティティのリストを生成しています。これを行うと、まだ問題が発生しているため、Entity Frameworkコードには問題がないことがわかります。
これが私のJSコードです:
var myDataSource = {
transport: {
read: {
url: function () {
return url;
},
type: 'post',
dataType: 'json'
},
parameterMap: function (options, operation) {
if (options.filter) {
KendoGrid_FixFilter(myDataSource, options.filter);
}
if (operation === "read") {
// convert the parameters to a json object
return kendo.stringify(options);
}
return options;
}
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
serverGrouping: true
schema: {
data: 'data',
groups: 'groups',
aggregates: 'aggregates',
total: 'total',
model: {
id: "id",
fields: {
id: { type: "number" },
name: { type: "string" },
description: { type: "string" }
}
}
},
};
そして、これが私のWebAPIコントローラコードです。
[System.Web.Http.Route("api/MyEntity")]
[System.Web.Http.HttpPost]
public KendoGridEx<MyEntity, MyEntity> GetMyEntities(KendoGridApiRequest request)
{
var entList = new List<MyEntity>();
for (int i = 0; i < 10; i++)
{
var newEntity = new MyEntity
{
Id = i,
Name = "test",
Description = "description"
};
entList.Add(newEntity);
}
return entList.AsQueryable().ToKendoGridEx<MyEntity, MyEntity>(request);
}
そのため、「名前」列に「テスト」の値を含む「含む」フィルターを設定すると、上記のエラーが発生します。理由に関するアイデアはありますか?
できることは、剣道グリッドがサーバーに送信する前にプロパティ名を変更することです。
したがって、filter.field値「name」は「Name」に変換されます。
この変更されたKendoGrid_FixFilter JavaScript関数を参照してください。
// kendoDataSource = kendo.data.DataSource
// filter = kendo filter
function KendoGrid_FixFilter(kendoDataSource, kendoFilter, depth) {
if ((!kendoDataSource) || (!kendoFilter)) return;
if (!depth) depth = 0;
// console.log(depth + " - FixDatesInFilter:" + JSON.stringify(kendoFilter));
$.each(kendoFilter.filters, function (idx, filter) {
//console.log("filter = " + idx + " = " + JSON.stringify(filter));
if (filter.hasOwnProperty("filters")) {
depth++;
KendoGrid_FixFilter(kendoDataSource, filter, depth);
}
else {
$.each(kendoDataSource.schema.model.fields, function (propertyName, propertyValue) {
if (filter.field == propertyName) {
// console.log("before = " + filter.field);
filter.field = filter.field.toPascalCase();
// console.log("after = " + filter.field);
}
if (filter.field == propertyName && propertyValue.type == 'date') {
filter.value = kendo.toString(filter.value, _DefaultDateFormat); // "MM/dd/yyyy"
// console.log("changed = " + filter.value);
}
});
}
});
}
この関数はデータソースですでに使用しています。
CamelCase / PascalCaseのサンプルコードは次のようになります。
String.prototype.toCamelCase = function () {
console.log("String.prototype.toCamelCase");
return this
.replace(/\s(.)/g, function ($1) { return $1.toUpperCase(); })
.replace(/\s/g, '')
.replace(/^(.)/, function ($1) { return $1.toLowerCase(); });
};
String.prototype.toUpperCaseFirstChar = function () {
console.log("String.prototype.toUpperCaseFirstChar");
return this.substr(0, 1).toUpperCase() + this.substr(1);
};
String.prototype.toPascalCase = function () {
console.log("String.prototype.toPascalCase");
return this.toCamelCase().toUpperCaseFirstChar();
};