【问题标题】:Missing OData envelope/context缺少 OData 信封/上下文
【发布时间】:2020-07-30 09:53:06
【问题描述】:

当我通过 OData 请求一些数据时,我将按请求获取数据,但不是 OData 信封/上下文。这意味着任何 OData 功能都不适用于客户端。

我试图了解我没有将 OData 信封与数据一起获取的原因。

设置如下:

  • .Net Core
  • OData
  • PostgreSQL

我正在使用以下网址请求数据:http://localhost:5000/odata/mycontroller/mydbview。

控制器类:

public class MyController : ODataController
{
    [EnableQuery]
    [ODataRoute("MyController/MyDBView")]
    public IActionResult GetSeasonView(int id)
    {
        var requestedItems = myTableContext.MyDBView;

        return Ok(requestedItems);
    }
}

EDM 模型:

public static IEdmModel GetEdmModel()
{
    var odataModelBuilder = new ODataConventionModelBuilder();
    odataModelBuilder.EntitySet<MyDataDto>("My");

    return odataModelBuilder.GetEdmModel();
}

数据对象如下:

[Table("datatable", Schema = "api")]
public class MyDataDto
{
    [Key] 
    public string Id { get; set; }
    public string Status { get; set; }
    public uint Total { get; set; }
  
    <Continues with more data>

视图是数据表的子集,如下所示:

[Table("datatable", Schema = "api")]
public class MyDBView
{
    [Key]
    public string id { get; set; }
    public string status { get; set; }
    public uint total { get; set; }
}

对此设置可能有什么问题有任何建议吗?顺便说一句,我尝试遵循本指南:https://www.laboremus.ug/post/using-sql-views-with-entity-framework-code-first

更新

我找到了问题,但仍然没有解决方案。问题是实体集注册为MyDataDTO,而返回值为MyDBView。

但我仍然不知道解决方案。

【问题讨论】:

  • 您想以 GET 还是 POST 的形式访问它?

标签: .net-core odata


【解决方案1】:

有几个问题,您的预期路线不符合 OData,这使得您难以解释您的预期用途,这是一个集合还是基于项目的请求?例如,您有一个未在方法中使用的 'id' 参数,并且路由前缀 MyController 与通过路由 My 注册的控制器不匹配。

对于这个解决方案,我可以演示两种方案的配置:

  • 用于返回整个视图的集合绑定函数
  • 一个项目绑定函数,用于返回范围为给定项目 ID 的视图

如果您想在端点方法上使用IActionResult 作为响应类型,您需要向 OData 模型注册 View DTO,或者可以返回 @ 987654324@.

  • 这可以工作,因为现在属性路由可以识别要返回的预期类型
  • IActionResult 让您可以灵活地返回错误响应或其他标准形式的响应。

让我们看看这个视图的两种方法,一个返回整个视图并支持$filter 查询选项,另一个从视图中返回单个项目的记录:

注意:我已更改您示例中的方法名称,以减少与配置的混淆

public class MyController : ODataController
{
    // example route: ~/My/DBView
    [EnableQuery]
    [HttpGet]
    public IActionResult DBView()
    {
        var requestedItems = myTableContext.MyDBView;
        return Ok(requestedItems);
    }

    // example route: ~/My(id)/asDBView
    [EnableQuery]
    [HttpGet]
    public IActionResult AsDBView(int key)
    {
        var requestedItem = myTableContext.MyDBView.Where(x => x.Id == key);
        return Ok(requestedItems);
    }
}

现在我们通过IEdmBuilder 将这些路由注册到 OData 模型中。要让视图支持查询,您需要指定数据集的概念名称,但这不需要对应实际的控制器。

public static IEdmModel GetEdmModel()
{
    var odataModelBuilder = new ODataConventionModelBuilder();
    // Initialize your OData EntitySets
    odataModelBuilder.EntitySet<MyDataDto>("My");

    // initialize the Custom DTOs
    odataModelBuilder.EntitySet<MyDbView>("MyDbViewFakeSet"); 
    // NOTE: Name is arbitrary, but MUST be unique across all EntitySets.

    // Register the Function endpoints on your "My" controller
    odataModelBuilder.EntitySet<MyDataDto>("My")
                     .Collection.Function("DBView")
                     .ReturnsCollectionFromEntitySet<MyDbView>("MyDbViewFakeSet");

    odataModelBuilder.EntitySet<MyDataDto>("My")
                     .EntityType.Function("asDBView")
                     .ReturnsFromEntitySet<MyDbView>("MyDbViewFakeSet");


    return odataModelBuilder.GetEdmModel();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 2018-09-30
    • 2021-08-05
    相关资源
    最近更新 更多