Search code examples
c#jsondynamics-crm

How can I deserialize and map this correctly?


I'm building a plugin for Dynamics CRM that consumes an API and this is my problem. When I get this Json string I can do the mapping easily. And I can call it properly.

{
  "userId": 1,
  "id": 2,
  "title": "qui est esse",
  "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}

My Code :

public string callRestAPI()
        {
            var request = (HttpWebRequest)WebRequest.Create("https://jsonplaceholder.typicode.com/posts/2");
            request.Method = "GET";
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36";
            request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
            var response =(HttpWebResponse)request.GetResponse();
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            string content = string.Empty;
            using (var stream = response.GetResponseStream())
            {
                using (var sr = new StreamReader(stream))
                {
                    return content = sr.ReadToEnd();
                }
            }
            throw new Exception($"api data is {content}");
        }

.. Mapping

public class RootObject
        {
            public int userId { get; set; }
            public int id { get; set; }
            public string title { get; set; }
            public string body { get; set; }
        }

..And now a sample of how I call it

string Consume = callRestAPI();
 var Accs = JsonConvert.DeserializeObject<RootObject>(Consume);
                        try
                        {
                            Entity createcontact = new Entity("contact");
                            createcontact["firstname"] = "Joe";
                            createcontact["lastname"] = Accs.title;
                            createcontact["emailaddress1"] = "[email protected]";

But when I get this type of string I get confused by it and I can't seem to do the calling of it correctly. My code works when I have to get the data from an API that return the first string but when I change to the second API that produces the below string nothing work and I'm just left confused.

{
"data": {
    "id": 2,
    "email": "[email protected]",
    "first_name": "Janet",
    "last_name": "Weaver",
    "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
}
}

Solution

  • Your first json snippet:

    {
      "userId": 1,
      "id": 2,
      "title": "qui est esse",
      "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
    }
    

    ... maps correctly to RootObject class.

    However, your second json represents hierarchy:

    {
       "data": {
           "id": 2,
           "email": "[email protected]",
           "first_name": "Janet",
           "last_name": "Weaver",
           "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
       }
    }
    

    ... there's the root object, then data object, so it can't be mapped to RootObject (so semantics-wise, it shouldn't be called "RootObject" anymore).

    So you've got 2 options:

    1. Just add a class that represents that hierarchy:

      public class Response
      {
          public RootObject data { get; set; }
      }
      

      ... and then:

      JsonConvert.DeserializeObject<Response>(json);
      
    2. Or, select the nested object json only:

      string dataJson = JObject.Parse(json).SelectToken("data").ToString();
      var data = JsonConvert.DeserializeObject<RootObject>(dataJson);