将List<KeyValuePair<string, object>>序列化为JSON

23

我在一个Web API项目中使用了字典,该字典被序列化为JSON格式:

{"keyname":{objectvalue},"keyname2:"....

由于我有重复的键,就不能再使用Dictionary类型了,而现在我正在使用List<KeyValuePair<string,object>>

但是它序列化的方式是这样的:

[{"Key":"keyname","Value":"objectvalue"}...
有没有办法让 List<KeyValuePair> 序列化的方式和字典一样呢?
谢谢。

1
如果您有重复的键,则不行。 - p.s.w.g
@user250773:你能否提供代码和输出结果,这样我们才能帮助你。 - Venkatesh Ellur
2个回答

35

如果您使用Newtonsoft Json.NET库,您可以执行以下操作。

定义一个转换器以按您想要的方式编写键/值对列表:

class MyConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        List<KeyValuePair<string, object>> list = value as List<KeyValuePair<string, object>>;
        writer.WriteStartArray();
        foreach (var item in list)
        {
            writer.WriteStartObject();
            writer.WritePropertyName(item.Key);
            writer.WriteValue(item.Value);
            writer.WriteEndObject();
        }
        writer.WriteEndArray();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // TODO...
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<KeyValuePair<string, object>>);
    }
}

然后使用转换器:

var keyValuePairs = new List<KeyValuePair<string, object>>
                    {
                        new KeyValuePair<string, object>("one", 1),
                        new KeyValuePair<string, object>("two", 2),
                        new KeyValuePair<string, object>("three", 3)
                    };

JsonSerializerSettings settings = new JsonSerializerSettings { Converters = new [] {new MyConverter()} };
string json = JsonConvert.SerializeObject(keyValuePairs, settings);

这将生成[{"one":1},{"two":2},{"three":3}]


有没有一个简单的示例来演示ReadJson方法的工作原理?我遇到了类似的问题,当我将Dictionary<string,string>的反序列化更改为List<KeyValuePair<string,string>>时,使用以下格式:{"key1":"test", "key1":"12345678", "key2":"ABC", } - user250773
@user250773 这篇博客应该足够让你了解如何进行JSON反序列化。 - Patrick Quirk
如果你想使用 IEnumerable<...>,你可以在方法中使用:CanConvert(Type type){ return GetType(objectType) == typeof(KeyValuePair<string, object>); } ,其中 GetType 是 static Type GetType(Type type) { foreach (Type intType in type.GetInterfaces()) { if (intType.IsGenericType && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { return intType.GetGenericArguments()[0]; } } return null; } - maliness
3
ReadJson应该被如何重写? - Euridice01

0

我会稍微修改接受的答案

public class MyConverter : JsonConverter<List<KeyValuePair<string, object>>>
{
    public override void WriteJson(JsonWriter writer, List<KeyValuePair<string, object>> value, JsonSerializer serializer)
    {
        List<KeyValuePair<string, object>> list = new(value);

        var keys = list.Select(x => x.Key).Distinct();

        writer.WriteStartObject();

        foreach (var key in keys) {
            var values = list.Where(item => item.Key == key).ToList();
            writer.WritePropertyName(values[0].Key);

            if (values.Count() == 1)
            {                    
                writer.WriteValue(values[0].Value);
            }
            else
            {
                writer.WriteStartArray();
                writer.WriteValue(string.Join(", ", values.Select(v => v.Value)));
                writer.WriteEndArray();
            }               
        }
        writer.WriteEndObject();

    }    

    public override List<KeyValuePair<string, object>>? ReadJson(JsonReader reader, Type objectType, List<KeyValuePair<string, object>>? existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接