如何使用来自Microsoft.OData.Client的DataServiceContext调用启用OD​​ata的MVC路由?

时间:2018-10-05 19:59:22

标签: .net json asp.net-core odata asp.net-core-2.0

我的.Net Core API中有一条简单的路由,可以手动处理ODataQuerySettings实例。我很难使用OData客户端软件包中的DataServiceContext类来调用此API。甚至可以将DataServiceContext与启用OData的简单MVC路由一起使用?还是我需要以其他方式公开数据以符合更严格的OData标准?


API示例

[AllowAnonymous]
[HttpGet("Products")]
public ActionResult<PageResult<IEnumerable<Product>>> GetData(
    ODataQueryOptions<Product> oDataQueryOptions)
{
    IEnumerable<Product> data = ProductService.GetData();

    IQueryable results = data
        .AsQueryable()
        .Skip(oDataQueryOptions.Skip?.Value ?? 0)
        .Take(oDataQueryOptions.Top?.Value ?? 3);

    return new OkObjectResult(
        new PageResult<object>(
            results.Cast<object>(),
            Request.GetNextPageLink(3),
            data.Length));
}

使用此API提取结果时,我得到了预期的值:

  • URL:localhost/api/Products?$skip=1
  • 结果:
{
    "items": [{
            "id": 2,
            "text": "Second"
        }, {
            "id": 3,
            "text": "Third"
        }, {
            "id": 4,
            "text": "Fourth"
        }
    ],
    "nextPageLink": "http://localhost/api/products?$skip=4",
    "count":9
}

消费应用

然后我继续使用Microsoft.OData.Client NuGet软件包(更具体地说是v7.5.1)创建一个示例客户端应用程序。

这是一个简单客户端的外观:

class Product
{
    public int Id { get; set; }
    public string Text { get; set; }
}

class Program
{
    static void Main()
    {
        var context = new DataServiceContext(new Uri("http://localhost/api"));

        var results = context
            .CreateQuery<Product>("products")
            .Skip(1)
            .ToList();
    }
}

调用ToList来获取/实现结果时,出现以下异常:

  

System.InvalidOperationException:响应有效负载不是有效的响应有效负载。请确保顶级元素是有效的Atom或JSON元素或属于“ http://docs.oasis-open.org/odata/ns/data”命名空间。

这似乎与以下事实有关:我没有返回“标准ODATA”响应,而是返回了原始json。

然后我尝试像这样在DataServiceContext上使用Json格式,但没有帮助:

var context = new DataServiceContext(new System.Uri("http://localhost/api"));
context.Format.UseJson(CreateEdmModel())       

...

private static IEdmModel CreateEdmModel()
{
    var model = new EdmModel();
    model.AddEntityType(typeof(Product).Namespace, nameof(Product));

    return model;
}

如何使用消费者应用程序中的DataServiceContext从API正确获取结果?我看到了两种可能性,但我都需要帮助:

  1. 更改使用者以使其与原始Json输出一起使用

这应该可行,但是现在我想知道我是否需要在客户端中添加额外的逻辑(例如构建EDM模型),以及是否失去一些功能,例如无法使用{{1 }}方法会自动遍历OData服务中的页面并进行汇总。

  1. 更改API本身的输出以发出“与ODATA兼容”的Json

听起来这将使消费者的工作量最少。但是,在保持手动分页的同时,我该怎么做(即我不能在纯自动路由上使用标准.GetAllPages[EnableQuery]返回值,因为我需要将OData属性传递到我们的Dapper层中:这里没有ORM)。我知道有一些专用于OData的Json模式,例如“ application / json; odata.metadata = minimal”,它与我现在正在输出的内容不同。

我过去曾经使用过WCF数据服务,并且不记得遇到这种问题:当时,我能够将IQueryable连接到WCF服务,而无需创建特殊的输出格式甚至在客户端中构建任何Edm模型。

0 个答案:

没有答案