您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Newtonsoft JSON.NET解析为自定义键/值对对象的数组

Newtonsoft JSON.NET解析为自定义键/值对对象的数组

您似乎想要Dictionary<string, string>在JSON中将a表示为对象数组,其中每个嵌套对象都有一个来自字典的键和值。您可以使用以下转换器进行操作:

public class DictionaryToDictionaryListConverter<TKey, TValue> : JsonConverter 
{
    class DictionaryDTO : Dictionary<TKey, TValue>
    {
        public DictionaryDTO(KeyValuePair<TKey, TValue> pair) : base(1) { Add(pair.Key, pair.Value); }
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(IDictionary<TKey, TValue>).IsAssignableFrom(objectType) && objectType != typeof(DictionaryDTO);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader);
        var dict = (IDictionary<TKey, TValue>)(existingValue as IDictionary<TKey, TValue> ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator());
        if (token.Type == JTokenType.Array)
        {
            foreach (var item in token)
                using (var subReader = item.CreateReader())
                    serializer.Populate(subReader, dict);
        }
        else if (token.Type == JTokenType.Object)
        {
            using (var subReader = token.CreateReader())
                serializer.Populate(subReader, dict);

        }
        return dict;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var dict = (IDictionary<TKey, TValue>)value;
        // Prevent infinite recursion of converters by using DictionaryDTO
        serializer.Serialize(writer, dict.Select(p => new DictionaryDTO(p)));
    }
}

然后在容器类中使用它,如下所示:

public class RootObject
{
    [JsonProperty("value")]
    [JsonConverter(typeof(DictionaryToDictionaryListConverter<string, string>))]
    public Dictionary<string, string> Value { get; set; }
}

请注意,如果键不是唯一的,转换器将在读取过程中引发异常。

对于AddressValue您可以使用下面的转换器:

public class AddressValueConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(AddressValue);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var addressValue = (existingValue as AddressValue ?? new AddressValue());
        var token = JObject.Load(reader);
        var property = token.Properties().SingleOrDefault();
        if (property != null)
        {
            addressValue.Label = property.Name;
            addressValue.Value = (string)property.Value;
        }
        return addressValue;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var addressValue = (AddressValue)value;
        serializer.Serialize(writer, new Dictionary<string, string> { { addressValue.Label, addressValue.Value } });
    }
}

然后按以下方式使用它:

[JsonConverter(typeof(AddressValueConverter))]
public class AddressValue
{
    public string Label { get; set; }
    public string Value { get; set; }
}

public class RootObject
{
    [JsonProperty("value")]
    public List<AddressValue> Value { get; set; }
}

演示在这里摆弄了这两种选择。

dotnet 2022/1/1 18:19:02 有419人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶