【问题标题】:mapping shared POCO to oData controllers with plural names将共享 POCO 映射到具有复数名称的 oData 控制器
【发布时间】:2016-03-18 23:09:18
【问题描述】:

我有一个名为LoggerEntriesController 的ODataController,它返回WebModels.LoggerEntry 的POCO 类型。 POCO 位于客户端和服务器之间共享的外部库中。

我这样注册EntitySet

var builder = new ODataConventionModelBuilder();
builder.EntitySet<WebModels.LoggerEntry>("LoggerEntries");
config.MapODataServiceRoute("odata", "api", builder.GetEdmModel());

在我的/api 元数据中我看到:

{
  "@odata.context":"http://localhost:3177/api/$metadata","value":[
    {
      "name":"LoggerEntries","kind":"EntitySet","url":"LoggerEntries"
    },{
      "name":"LoggerEntry","kind":"EntitySet","url":"LoggerEntry"
    }
  ]
}

这会导致 Simple.Odata.Client 无法将 LoggerEntry 解析为 /api/LoggerEntries url,并且在进行强类型调用时出现 404,例如:

await this.Client
    .For<LoggerEntry>()
    .Set(new LoggerEntry()
    {
        Title = title,
        Message = message,
    })
    .InsertEntryAsync();

这让我相信/api 元数据应该是这样的:

{
  "@odata.context":"http://localhost:3177/api/$metadata","value":[
    {
      "name":"LoggerEntry","kind":"EntitySet","url":"LoggerEntries"
    }
  ]
}

我不确定我做错了什么,或者我需要做什么才能从 ODataConventionModelBuilder 获取后一个元数据结果。

【问题讨论】:

  • 在服务文档(又名元数据)中,name 属性实际上应该是 LoggerEntries,因为这是您在配置中为实体集指定的名称。如果在客户端代码中将 For&lt;LoggerEntry&gt;() 替换为 For("LoggerEntries") 会发生什么?
  • 我认为这只是强类型客户端方法的强烈变化。在元数据中,如果名称和 URL 都是复数,那么客户端不会假设类型也是复数吗?我的理解是,这种元数据映射也是客户端如何知道类型名称是单数,而集合是复数。诚然,我没有参考备份最后一个。
  • @lencharest,澄清客户端调用是需要保持不变以使用特定共享类型保持强类型化的部分。
  • 我只是要求你做一个实验来帮助隔离问题。
  • 明确地说,您可能面临两个问题。 1)如果您只在服务中配置1个实体集,那么您的服务文档应该只有1个条目,并且应该命名为LoggerEntries。 2) Simple.OData.Client 是否知道在创建请求 URI 时应该将类型名称 LoggerEntry 复数?

标签: c#-4.0 asp.net-web-api odata asp.net-web-api2 simple.odata


【解决方案1】:

我认为问题在于您的服务元数据中同时包含 LoggerEntries 和 LoggerEntry 实体集,Simple.OData.Client 选择第一个满足其规则的实体集(这很简单,反映了库名称 - 它接受任何内容与复数或单数形式的名称匹配)。

S.O.D 版本 5 将对命名约定有更严格的控制,但即使使用这个版本,我相信您应该能够通过明确指定实体集名称来解决问题,即

await this.Client
    .For<LoggerEntry>("LoggerEntries")
    .Set(new LoggerEntry()
    {
        Title = title,
        Message = message,
    })
    .InsertEntryAsync();

【讨论】:

  • 当前版本的 Simple.OData.Client 是否检索和解析服务文档?
  • 是的。但只有一次,它会缓存元数据文档。
  • 通过阅读代码(我承认我还没有真正使用过 SOD),它正在检索 元数据 文档(例如,http://host/$metadata),但不是service 文档(例如,http://host/,服务基础 URI 处的文档)。
  • 哦,是的,我的意思是服务元数据文档,它是由 OData 协议指定的。不确定您在 OData 通信上下文中指的是什么其他文档。
  • @DrydenMaker 发布的 JSON 是 service document,它是 OData service model 的一部分。
猜你喜欢
  • 2013-02-22
  • 2013-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多