Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If T can be enumerated, it can not be deserialized using ReadAs<T>. #4

Closed
hamamotsu opened this issue Nov 19, 2018 · 1 comment
Closed
Assignees
Labels
bug Something isn't working

Comments

@hamamotsu
Copy link

Usage environment

  • version : 1.6.3
  • platform : aspnetcore2.1 and LINQPad

Reproduction procedure

  1. Create Get request.
  2. Call SendAsync.
  3. Deserialize the response to IEnumerable<T>
ODataHttpClient.Serializers.JsonSerializer.Default = ODataHttpClient.Serializers.JsonSerializer.General;
var client = new ODataClient(new HttpClient(), user, pass);

var uri = "http://example.com/data/ProductContents?$filter=Id eq 1 or Id eq 2";
var request = Request.Get(uri);
var response = await client.SendAsync(request);
var values = response.ReadAs<IEnumerable<ProductContent>>("$.value");

Error Detail

Throw JsonSerializationException

Exception message

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ProductContent' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.Path 'value', line 1, position 94.

Response Body

{"@odata.context":"http://example.com/data/ProductContents/$metadata#ProductContents","value":[{"Id":1,"ProductManageId":1,"ContentType":1,"Heading":"empty","Content":"hogehoge","SortOrder":0},{"Id":2,"ProductManageId":1,"ContentType":2,"Heading":"empty","Content":"hogehoge","SortOrder":0}]}

It is possible to deserialize using JToken or "JObject.ToObjedct ()" without using the ReadAs method.

JObject Pattern

var values = response.ReadAs<JArray>("$.value");
var objects = values.Select(v => ((JObject)v).ToObject<ProductContent>());

JToken Pattern

private static readonly JsonSerializerSettings _general = new JsonSerializerSettings
{
  Converters ={ new ByteArrayConverter() }
};

var token = JToken.Parse(response.Body).SelectToken("$.value");
var objects = token.ToObject<IEnumerable<ProductContent>>(Newtonsoft.Json.JsonSerializer.Create(_general));
@iwate iwate self-assigned this Nov 20, 2018
@iwate iwate added the bug Something isn't working label Nov 20, 2018
iwate added a commit that referenced this issue Nov 20, 2018
@iwate
Copy link
Owner

iwate commented Nov 20, 2018

@hamamotsu Thank you for your report!
I fix and release new version package on nuget. please update package of your project.
https://www.nuget.org/packages/ODataHttpClient/1.6.4

@iwate iwate closed this as completed Nov 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants