Error from Expand in DataServiceQuery in OData Client
Asked Answered
H

1

6

I am testing OData .Net Client as following:

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

And, I am getting an exception of

"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."

I also tested the same service from a browser with

http://localhost:6851/Orders(1)?$expand=OrderDetails

Then, the service returns

{ "@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 also captures same json data to the client program, but the client modules doesn't read it and raises the exception.

If I remove the "expand", it works fine.

What am I doing wrong ?

Holmium answered 23/8, 2015 at 14:1 Comment(0)
C
0

I can reproduce the problem in .NET Core 3.1 with the TripPin OData V4 Sample Service as follows:

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);
        }
    }
}

Exception has occurred: CLR/Microsoft.OData.ODataException When writing a JSON response, a user model must be specified and the entity set and entity type must be passed to the ODataMessageWriter.CreateODataResourceWriter method or the ODataResourceSerializationInfo must be set on the ODataResource or ODataResourceSet that is being written.

The cause:

This issue affects where we don't have NavigationPropertyBinding within an Entity Set

It does work when trying another service endpoint.

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

The difference with the latter is the 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" />

This can be added by annotating the data model with the Contained attribute:

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

As alternative, the containment relation can also be added with the ODataConventionModelBuilder.

var modelBuilder = new ODataConventionModelBuilder();
modelBuilder
    .EntityType<Person>()
    .ContainsMany(p => p.Trips);
Claudeclaudel answered 26/5, 2020 at 14:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.