如何使用常见类型的命名属性为JSON建模

时间:2018-12-16 20:57:45

标签: c# json json.net deserialization json-deserialization

以下是示例JSON:

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

我正在尝试序列化为C#类,其中NotificationInfo实例的EventName是键event.namespace1event2.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; }
}

我创建了一个dotnetfiddle:https://dotnetfiddle.net/8oqniT

1 个答案:

答案 0 :(得分:2)

使事情正常运行的最简单方法是将模型更改为以下内容:

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

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

JSON中的事件名称将成为列表中字典的键。

提琴:https://dotnetfiddle.net/P3yD3p

但是,正如您从小提琴中看到的那样,此模型的使用可能有点尴尬。我认为,更好的方法是保留原始模型并使用自定义JsonConverter处理翻译。这是转换器所需的代码:

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();
    }
}

要使用它,只需将[JsonConverter]属性添加到Notifications属性中,如下所示:

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

提琴:https://dotnetfiddle.net/vkjXC0