1

I've got a json file containing

{
  "Accounts": null,
  "AccountTypes": null,
  "Actions": null,
  "Photos": [
    {
      "Instance": "...",
      "Key": "..."
    },
    ....
  ]
}

Now I want to get all the Instance properties from the Photo objects. I've got the following code:

var photos = new List<Photo>();

string json = File.ReadAllText(file);
dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(object));
var jsonPhotos = jsonObj.Photos as IEnumerable<dynamic>;
var instances = jsonPhotos.Select(x => x.Instance);

foreach (var instance in instances)
    photos.Add(new Photo
    {
        Document = Convert.FromBase64String(instance)
    });

However, jsonPhotos.Select(x => x.Instance); isn't returning anything...

I am able to get things working by using

var instances = new List<string>();

foreach (var photo in jsonPhotos)
    instances.Add(photo.Instance.Value);

But can I solve this in a LINQ way?

3
  • 1
    your json format is wrong. there is a comma missing after "Instance": "...", if you fix it the problem goes away. Commented Jul 10, 2020 at 9:52
  • Sorry, the typo only exists in my question here. In my real code there was never a typo Commented Jul 10, 2020 at 9:57
  • but jsonPhotos.Select(x => x.Instance); does return something Commented Jul 10, 2020 at 10:45

2 Answers 2

2

Why just don't use Json.Linq for that? Parse JSON to JObject instance, then map every token from Photos array to Photo instance (I've omitted Convert.FromBase64String because OP sample doesn't have a valid base64 data, but converting Instance value can be easily added)

var json = JObject.Parse(jsonString);

var photos = json["Photos"]
    .Select(token => new Photo
    {
        Document = token["Instance"]?.Value<string>()
    })
    .ToList();
Sign up to request clarification or add additional context in comments.

Comments

0

The .Select(x => x.Instance) indeed returns ... on .NET Core 3.1. Can you verify that the contents of the json variable are actually what you expect?

Specifically

jsonPhotos.Select(x => x.Instance);

works as expected, while

jsonPhotos.Select(x => x.SomeNonExistingProperty);

enumerates nothing / empty values.


For example, this code prints Instance A, then Instance B, then nothing twice:

var json = @"
{
    ""Photos"": [
    {
        ""Instance"": ""Instance A"",
        ""Key"": ""...""
    },
    {
        ""Instance"": ""Instance B"",
        ""Key"": ""...""
    }]
}";

var jsonObj = JsonConvert.DeserializeObject<dynamic>(json);
var jsonPhotos = jsonObj.Photos as IEnumerable<dynamic>;

var instances = jsonPhotos.Select(x => x.Instance);
foreach (var instance in instances)
{
    Console.WriteLine(instance);
}

// In contrast, this one will print empty lines.
instances = jsonPhotos.Select(x => x.SomeNonExistingProperty);
foreach (string instance in instances)
{
    Console.WriteLine(instance);
}

I took the liberty to change the deserialization to dynamic directly, but it also works with the original code from the question.

2 Comments

The typo is not the issue, since that one results in a JsonReaderException.
Sorry, the typo only exists in my question. In my real code there is no typo... I've edit my question and fixed the typo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.