0

I want to be able to access the JSON objects with LINQ when the JSON is returned.

I have referred to Send JSON via POST in C# and Receive the JSON returned? and Send and receive json via HttpClient

This is what I have so far

 public static async Task<string> GetMailTip(string user)
        {
            var jsonData = new StringContent(FormatJson(CreateJsonGettingMailTip(user)), Encoding.UTF8, "application/json");
            var payload = await client.PostAsync($"https://graph.microsoft.com/v1.0/users/{user}/getMailTips", jsonData);
            string responseContent = "";

            if (payload.Content != null)
            {
                responseContent = await payload.Content.ReadAsStringAsync();

                Console.WriteLine(responseContent);
            }

            var getMailTip = responseContent["value"]
              .Children()
              .Where(i => i != null)
              .Select(c => c[""][""].Value<string>().Trim());

            return responseContent;
        }

The returned JSON is

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(microsoft.graph.mailTips)",
    "value": [
        {
            "emailAddress": {
                "name": "",
                "address": ""
            },
            "automaticReplies": {
                "message": "",
                "messageLanguage": {
                    "locale": "",
                    "displayName": ""
                },
                "scheduledStartTime": {
                    "dateTime": "",
                    "timeZone": ""
                },
                "scheduledEndTime": {
                    "dateTime": "",
                    "timeZone": ""
                }
            }
        }
    ]
}

I want to be able to access the message property in the JSON with LINQ

Any help would be appreciated

Armz
  • 85
  • 1
  • 7
  • Its unclear what you are asking, or what you are wanting to do. – TheGeneral Aug 15 '20 at 23:44
  • 1
    You need to deserialize `responseContent` to c# class object. You can use https://www.jsonutils.com/ to create c# classes for the json string you have. – Chetan Aug 15 '20 at 23:47
  • @MichaelRandall please see revised question – Armz Aug 15 '20 at 23:48
  • @ChetanRanpariya would it be possible to do it without creating a class ? – Armz Aug 15 '20 at 23:49
  • @Armz technically yes, but why?? OO languages have classes. You have written classes, many of them I'm sure. What is your aversion to it in this case? – Caius Jard Aug 15 '20 at 23:56
  • @CaiusJard to be honest I just want something quick. I have also been using LINQ for the majority of my functions – Armz Aug 15 '20 at 23:59
  • If you don't want to create classes then you need to convert json string to json object. https://stackoverflow.com/questions/22870624/convert-json-string-to-json-object-c-sharp – Chetan Aug 16 '20 at 01:07
  • 1
    Does this answer your question? [Linq query JObject](https://stackoverflow.com/questions/17781996/linq-query-jobject) – Chetan Aug 16 '20 at 01:09
  • 1
    If you want something quick then there isn't much quicker than pasting your JSON into a service like QuickType.io, getting it to generate the classes and json deserialise code for you, pasting it into your project with a one liner (that they advise on too) to turn your json into classes really is the way to go.. But definition it is faster to do that than paste the Json into SO and write a Q;having these things as proper classes will make it a lot easier, faster and more accurate to write queries than turning them into a dictionary of dictionaries of dictionaries of dictionaries of strings etc – Caius Jard Aug 16 '20 at 05:52
  • (And if you hadn't imposed this restriction that I'm now quizzing you on I could have answered 4 hours sooner! :) ) – Caius Jard Aug 16 '20 at 05:53
  • @CaiusJard Thank you for your answer ! Honestly, I am open to different ways of doing this. I wanted to know how it could be done quicker. – Armz Aug 16 '20 at 09:15
  • @ChetanRanpariya I will check it out thank you – Armz Aug 16 '20 at 12:58
  • @ChetanRanpariya I used JObject o = JObject.Parse(responseContent); and it worked for me. Thank you. – Armz Aug 16 '20 at 16:02

1 Answers1

1

You go to http://quicktype.io (or similar online service, jsonutils, json2csharp, or use the Visual studio Paste Json as Classes feature - of all the sites that do this QT is the most full featured) to turn your json into classes. This makes it nicer to work with:

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using SomeNamespaceHere;
//
//    var rootClassNameHere = RootClassNameHere.FromJson(jsonString);

namespace SomeNamespaceHere
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class RootClassNameHere
    {
        [JsonProperty("@odata.context")]
        public Uri OdataContext { get; set; }

        [JsonProperty("value")]
        public Value[] Value { get; set; }
    }

    public partial class Value
    {
        [JsonProperty("emailAddress")]
        public EmailAddress EmailAddress { get; set; }

        [JsonProperty("automaticReplies")]
        public AutomaticReplies AutomaticReplies { get; set; }
    }

    public partial class AutomaticReplies
    {
        [JsonProperty("message")]
        public string Message { get; set; }

        [JsonProperty("messageLanguage")]
        public MessageLanguage MessageLanguage { get; set; }

        [JsonProperty("scheduledStartTime")]
        public ScheduledTime ScheduledStartTime { get; set; }

        [JsonProperty("scheduledEndTime")]
        public ScheduledTime ScheduledEndTime { get; set; }
    }

    public partial class MessageLanguage
    {
        [JsonProperty("locale")]
        public string Locale { get; set; }

        [JsonProperty("displayName")]
        public string DisplayName { get; set; }
    }

    public partial class ScheduledTime
    {
        [JsonProperty("dateTime")]
        public string DateTime { get; set; }

        [JsonProperty("timeZone")]
        public string TimeZone { get; set; }
    }

    public partial class EmailAddress
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("address")]
        public string Address { get; set; }
    }

    public partial class RootClassNameHere
    {
        public static RootClassNameHere FromJson(string json) => JsonConvert.DeserializeObject<RootClassNameHere>(json, SomeNamespaceHere.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this RootClassNameHere self) => JsonConvert.SerializeObject(self, SomeNamespaceHere.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
}

(I chose "SomeNamespaceHere" and "RootClassNameHere" for the relevant names of namespace and class root; you might choose different)

And then you use it like this (the deser step will work differently depending on the service you used):

var rootClassNameHere = RootClassNameHere.FromJson(jsonString); //deser
var someLinq = rootClassNameHere.Value.Select(v => v.AutomaticReplies.Message); //query
Caius Jard
  • 72,509
  • 5
  • 49
  • 80