2

how to Deserialize JSON with nested List in C#, my Activities are always null. please help me. Not able to get where I am going wrong. Any help would be really appreciated.

I am trying to deserialize the code, but not getting Activities . My Project is:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;

public class Program
{
    public static void Main()
    {
        string json = @"
            {
  ""Title"": ""test"",
  ""Id"": ""SR21576"",
  ""CreatedDate"": ""2016-12-10T09:21:06+03:30"",
  ""DisplayName"": ""SR21576 : test"",
  ""Description"": ""10"",
  ""AlternateContactMethod"": null,
  ""AffectedUser"": null,
  ""AssignedToUser"": ""XXX\\BB Team"",
  ""CustomerCode"": ""00000000-0000-0000-0000-000000000000"",
  ""CustomerName"": null,
  ""ContractId"": ""00000000-0000-0000-0000-000000000000"",
  ""ContractTitle"": null,
  ""ContractDetailsId"": ""00000000-0000-0000-0000-000000000000"",
  ""ContractDetailsTitle"": null,
  ""CRMLink"": null,
  ""LeadId"": ""00000000-0000-0000-0000-000000000000"",
  ""LeadTitle"": null,
  ""Urgency"": ""b02d9277-a9fe-86f1-e95e-0ba8cd4fd075"",
  ""Priority"": ""1e070214-693f-4a19-82bb-b88ee6362d98"",
  ""Source"": ""57e11419-ac27-a6fa-97f1-0ec2a9722807"",
  ""Area"": ""3c5e6037-b057-5745-4d89-e95f67d3236b"",
  ""SupportGroup"": ""ae536997-8124-85e7-496e-225b7991a450"",
  ""Attachments"": [ ],
  ""Activities"": [
    {
      ""<Id>k__BackingField"": ""ffe60a69-f3c8-adbe-9bbd-4050d766cc81"",
      ""<ActivityID>k__BackingField"": ""MA21578"",
      ""<Title>k__BackingField"": ""a"",
      ""<Status>k__BackingField"": ""Ready"",
      ""<TypeOfActivity>k__BackingField"": 1
    },
    {
      ""<Id>k__BackingField"": ""91286e74-6a39-964f-040f-5daf99e84792"",
      ""<ActivityID>k__BackingField"": ""RA21579"",
      ""<Title>k__BackingField"": ""b"",
      ""<Status>k__BackingField"": ""Ready"",
      ""<TypeOfActivity>k__BackingField"": 0
    },
    {
      ""<Id>k__BackingField"": ""9754f1a1-d37b-265a-087a-f6688808dbeb"",
      ""<ActivityID>k__BackingField"": ""MA21577"",
      ""<Title>k__BackingField"": ""c"",
      ""<Status>k__BackingField"": ""Active"",
      ""<TypeOfActivity>k__BackingField"": 1
    },
    {
      ""<Id>k__BackingField"": ""d959cac5-cb78-a3fb-09e2-76da1b5381b2"",
      ""<ActivityID>k__BackingField"": ""MA21580"",
      ""<Title>k__BackingField"": ""d"",
      ""<Status>k__BackingField"": ""Ready"",
      ""<TypeOfActivity>k__BackingField"": 1
    }
  ],
  ""Status"": ""InProgress""
}";


        ServiceRequest items = JsonConvert.DeserializeObject<ServiceRequest>(json);

        Console.WriteLine("Area: " + items.Area);
        Console.WriteLine("CRMLink: " + items.CRMLink);

        Console.WriteLine("Number of Activities: " + items.Activities.Count);

        int i = 0;
        //Activities are null why???????
        foreach (var type in items.Activities)
        {
            i++;
            Console.WriteLine("Activities item number " + i);
            Console.WriteLine("ActivityID: " + type.ActivityID);
            Console.WriteLine("Id: " + type.Id);
            Console.WriteLine("Status: " + type.Status);
            Console.WriteLine("Title: " + type.Title);
            Console.WriteLine("TypeOfActivity: " + type.TypeOfActivity);
            Console.WriteLine();
        }
    }
}

[Serializable]
public class Activity
{
    public Guid Id { get; set; }
    public String ActivityID { get; set; }
    public String Title { get; set; }
    public String Status { get; set; }

    public ActivityType TypeOfActivity { get; set; }
}

[Serializable]
public enum ActivityType
{
    ReviewActvity,
    ManualActivity
}

[Serializable]
public class Attachment
{
    [Required]
    public string FileName { get; set; }
    [Required]
    public string ServerFileName { get; set; }
    public bool ToRemove { get; set; }
    [Required]
    public string AttachedByUser { get; set; }

}

[Serializable]
public class ServiceRequest
{
    [Required]
    public string Title { get; set; }
    public String Id { get; set; }
    public DateTime CreatedDate { get; set; }
    public string DisplayName { get; set; }
    [Required]
    public string Description { get; set; }
    public string AlternateContactMethod { get; set; }
    public string AffectedUser { get; set; }
    public string AssignedToUser { get; set; }
    public Guid CustomerCode { get; set; }
    public string CustomerName { get; set; }
    public Guid ContractId { get; set; }
    public string ContractTitle { get; set; }
    public Guid ContractDetailsId { get; set; }
    public string ContractDetailsTitle { get; set; }
    public string CRMLink { get; set; }
    public Guid LeadId { get; set; }
    public string LeadTitle { get; set; }
    public Guid Urgency { get; set; }
    public Guid Priority { get; set; }
    public Guid Source { get; set; }
    public Guid Area { get; set; }
    public Guid SupportGroup { get; set; }
    public List<Attachment> Attachments { get; set; }
    public List<Activity> Activities { get; set; }
    public string Status { get; set; }
}
8
  • Why is the JSON actually double-quoted? At present, your string is not valid JSON. Commented Dec 10, 2016 at 9:11
  • Is it real json: ""<Id>k__BackingField"": ""ffe60a69-f3c8-adbe-9bbd-4050d766cc81" ? This "<Id>k__BackingField" instead of id is reason, becasue you couldn't deserialize it. Commented Dec 10, 2016 at 9:13
  • Does it properly deserialize if you remove the k__BackingField marker (e.g. <Id>k__BackingField to Id)? That's being generated by the default context resolver. You may want to set IgnoreSerializableAttribute = true otherwise. Commented Dec 10, 2016 at 9:13
  • @dbc - Ah, my bad - didn't notice the @ prefix, whoops! Thanks. Still, it won't deserialize properly with the <Id>k__BackingField stuffs. Is this JSON generated by an API? It should just be "Id" : "..." Commented Dec 10, 2016 at 9:16
  • 1
    @GeoffJames that's how the DataContractJsonSerializer Class handles auto-implemented properties. (edit) ref: conficient.wordpress.com/2014/05/22/… Commented Dec 10, 2016 at 9:19

2 Answers 2

5

Whoever originally generated the JSON for your Activities collection chose to serialize the fields of the objects. And since the class consists entirely of auto-implemented properties, you're getting the secret backing fields.

To force Json.NET to deserialize the public and private fields of Activity rather than its properties, mark the type with [JsonObject(MemberSerialization.Fields)]:

[Serializable]
[JsonObject(MemberSerialization.Fields)]
public class Activity
{
    public Guid Id { get; set; }
    public String ActivityID { get; set; }
    public String Title { get; set; }
    public String Status { get; set; }

    public ActivityType TypeOfActivity { get; set; }
}

Or, fix the code that originally generated the JSON to serialize the properties in preference to the fields. This seems to have been a conscious choice since the root type ServiceRequest has its properties serialized, not its fields.

Sample fiddle.

Sign up to request clarification or add additional context in comments.

Comments

0

Method 1: remove the [Serializable] attribute from the Activity class.

If not strictly necessary, the removal will prevent the default DataContractJsonSerializer from generating the extra markers.

Method 2: Configure the serializer to ignore the [Serializable] attribute:

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
new DefaultContractResolver { IgnoreSerializableAttribute = true };

Reference.

Comments

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.