1

Here's sample JSON:

{
    "notifications": [
        {
            "Profile.Guestbook.Post": {
                "TargetIntId": 1,
                "Digest": true,
                "DigestSchedule": "00 * * * * *"
            },
            "Profile.MediaEntry.Post": {
                "TargetIntId": 1,
                "Digest": true,
                "DigestSchedule": "00 * * * * *"
            }
        }
    ]
} 

I'm trying to serialize into C# classes, where the NotificationInfo instance's EventName is the value of the keys, event.namespace1 and event2.namespaceX

public class Preferences 
{
    public List<NotificationInfo> Notifications { get;set; }
}

public class NotificationInfo
{
    public string EventName { get;set; }
    public int TargetIntId { get;set; }
    public bool Digest { get;set; }
}

I created a dotnetfiddle: https://dotnetfiddle.net/8oqniT

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
enorl76
  • 2,562
  • 1
  • 25
  • 38
  • 1
    What do you get If you "Edit" / "Paste special" your JSON as classes in Visual Studio (see https://stackoverflow.com/questions/18526659/how-to-show-the-paste-json-class-in-visual-studio-2012-when-clicking-on-paste) – Richardissimo Dec 16 '18 at 21:46

1 Answers1

2

The easiest way to get things working is to change your model to the following:

public class Preferences
{
    public List<Dictionary<string, NotificationInfo>> Notifications { get; set; }
}

public class NotificationInfo
{
    public int TargetIntId { get; set; }
    public bool Digest { get; set; }
}

The event names from the JSON will be become the keys of the dictionary in the list.

Fiddle: https://dotnetfiddle.net/P3yD3p

However, this model can be a little bit awkward to use, as you can see from the fiddle. A better approach, in my opinion, is to keep your original model in place and use a custom JsonConverter to handle the translation. Here is the code you would need for the converter:

public class NotificationsConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<NotificationInfo>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var array = JArray.Load(reader);
        return array.Children<JObject>()
                    .SelectMany(jo => jo.Properties())
                    .Select(jp => new NotificationInfo
                    {
                        EventName = jp.Name,
                        TargetIntId = (int)jp.Value["TargetIntId"],
                        Digest = (bool)jp.Value["Digest"]
                    })
                    .ToList();
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

To use it, just add a [JsonConverter] attribute to your Notifications property like this:

    [JsonConverter(typeof(NotificationsConverter))]
    public List<NotificationInfo> Notifications { get; set; }

Fiddle: https://dotnetfiddle.net/vkjXC0

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300