OData Client

时间:2015-08-23 14:01:41

标签: json client odata expand

我正在测试OData .Net Client如下:

static void Main(string[] args)
    {
        var dataServiceContext = new Container(new Uri("http://localhost.fiddler:6851/"));

        var selectedOrders = from order in dataServiceContext.Orders.Expand("OrderDetails")
                                where order.OrderId==1
                                select order;

        DataServiceCollection<Order> orders = new DataServiceCollection<Order>(selectedOrders);        

        // Update Navigation
        orders[0].OrderDetails[0].Quantity=9999;

        dataServiceContext.SaveChanges();
    }

而且,我得到了

的例外

"When writing a JSON response, a user model must be specified and the entity set and entity type must be passed to the ODataMessageWriter.CreateODataEntryWriter method or the ODataFeedAndEntrySerializationInfo must be set on the ODataEntry or ODataFeed that is being written."

我还使用

从浏览器测试了相同的服务
http://localhost:6851/Orders(1)?$expand=OrderDetails

然后,服务返回

{ "@odata.context":"http://localhost:6851/$metadata#Orders/$entity","OrderId":1,"CustomerId":"KKKK9","OrderDetails":[
   {
      "OrderDetailId":1,"OrderId":1,"ProductId":1,"UnitPrice":10.00,"Quantity":1
   },
   {
      "OrderDetailId":2,"OrderId":1,"ProductId":2,"UnitPrice":20.00,"Quantity":2
   },
   {
      "OrderDetailId":6,"OrderId":1,"ProductId":3,"UnitPrice":30.00,"Quantity":33
   }
]}

Fiddler还将相同的json数据捕获到客户端程序,但客户端模块没有读取它并引发异常。

如果我删除&#34;展开&#34;,它可以正常工作。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我可以使用TripPin OData V4示例服务在.NET Core 3.1中重现该问题,如下所示:

using System;
using System.Net.Http;
using Simple.OData.Client;

namespace odata_simpleclient
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            HttpClientHandler clientHandler = new HttpClientHandler();
            clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
            HttpClient httpClient = new HttpClient(clientHandler);
            var settings = new ODataClientSettings(httpClient);
            settings.BaseUri = new Uri("https://services.odata.org/TripPinRESTierService/(S(juqvmnem2qpijynyewk4pld5))/");

            var client = new ODataClient(settings);
            var result = await client
                .For("People")
                .Key("russellwhyte")
                .NavigateTo("Trips")
                .FindEntriesAsync();

            Console.WriteLine(result);
        }
    }
}

发生异常:CLR / Microsoft.OData.ODataException 编写JSON响应时,必须指定用户模型,并且 实体集和实体类型必须传递给 ODataMessageWriter.CreateODataResourceWriter方法或 ODataResourceSerializationInfo必须在ODataResource或 正在写入的ODataResourceSet。

cause

此问题会影响我们在实体集中没有NavigationPropertyBinding的地方

当尝试另一个服务端点时,它确实起作用。

settings.BaseUri = new Uri("https://services.odata.org/v4/TripPinServiceRW/");

与后者的区别是ContainsTarget="true" NavigationProperty。

<NavigationProperty Name="Trips" Type="Collection(Microsoft.OData.Service.Sample.TrippinInMemory.Models.Trip)" />
<NavigationProperty Name="Trips" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Trip)" ContainsTarget="true" />

annotating the data model可以使用Contained属性来添加:

[Contained]
public List<Trip> Trips { get; set; }

或者,containment relation也可以与ODataConventionModelBuilder一起添加。

var modelBuilder = new ODataConventionModelBuilder();
modelBuilder
    .EntityType<Person>()
    .ContainsMany(p => p.Trips);