【问题标题】:KendoGridBinderEx - No property or field exists in typeKendoGridBinderEx - 类型中不存在属性或字段
【发布时间】:2015-09-02 15:04:17
【问题描述】:

我正在使用 AngularJS 和 KendoUI 来创建一个网格,该网格从 WebAPI 网络服务获取数据。对于网格,我希望允许服务器端排序、分页、过滤和分组。为此,我正在尝试使用KendoGridBinderEx 库。

我已经下载了 KendoGridBinderEx 源代码,运行示例项目,它运行良好。但是,当我在项目中执行完全相同的操作时,当我尝试对网格中的列进行过滤时出现以下错误:

System.Linq.Dynamic.ParseException:“MyEntity”类型中不存在属性或字段“test”

“test”是我在过滤器中输入的内容,所以它应该是过滤器文本;它不应该寻找名为“test”的属性或字段。

我已经调试并使用 Fiddler 看到请求中发送的请求的过滤器部分与示例中的工作请求完全相同,所以我认为问题不在请求端。

对于我的所有代码块,我都在简化一切以节省空间,并删除不相关的内容。例如,我正在删除我的数据库代码,并动态生成一个实体列表,因为这样做仍然会出现问题,因此我知道这不是我的实体框架代码的问题。

这是我的 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);
    }

因此,如果我在“名称”列上设置“包含”过滤器,值为“测试”,则会出现上述错误。关于为什么的任何想法?

【问题讨论】:

    标签: c# asp.net-web-api kendo-grid dynamic-linq automapper-3


    【解决方案1】:

    类型“MyEntity”中不存在属性或字段“test”..

    我认为只能找到值 Id,Name,Description.. 消息是“我搜索属性和字段..”

    而 Id、Name、Description 是唯一的“属性或字段”。

    --'test' 是一个值,而不是属性或字段--

    【讨论】:

    • 对,这就是我的重点。在我的代码中,我从来没有试图告诉它寻找一个名为“test”的属性或字段。错误信息很差。事实证明,我找到了答案,即我的实体和请求之间的案例(camel vs. Pascal)是不同的。
    【解决方案2】:

    经过一天的努力,我终于在今天发布了 SO。当然,在问这个问题几分钟后,我偶然发现了答案!

    问题最终是我的客户端 JS 代码和我的实体之间的列名大小写不同。在我的 WebApiConfig 中,我正在使用

            // Web API configuration and services
            var settings = config.Formatters.JsonFormatter.SerializerSettings;
            settings.Formatting = Formatting.Indented;
            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    

    此代码使得当我的 WebAPI 返回数据时,所有字段名称都转换为驼峰式。这是因为我想在 JS 端使用骆驼大小写的所有内容,但在 C# 端使用 Pascal 大小写。

    让我失望的第一件事是其他 KendoGridApiRequest 操作,例如 Sort,在属性名称方面似乎不区分大小写。另一件事是错误消息说它正在寻找过滤器值作为属性;它应该说“'MyEntity'类型中不存在属性或字段'name'”;那么我可能会立即知道是外壳把它扔掉了。

    现在我需要弄清楚如何将请求属性转换回 Pascal 大小写。在最坏的情况下,我必须将所有内容都转换为相同的情况,但这将是很多工作(实体比我的示例显示的要复杂得多)。

    【讨论】:

      【解决方案3】:

      您可以做的是在 kendo-grid 将这些属性名称发送到服务器之前修改属性名称。

      所以 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();
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-28
        • 1970-01-01
        • 2011-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-30
        相关资源
        最近更新 更多