簡體   English   中英

Json.NET 序列化字典<TKey, TValue>對比鍵值對<TKey, TValue>

[英]Json.NET serializing Dictionary<TKey, TValue> vs KeyValuePair<TKey, TValue>

考慮以下代碼

var dict = new Dictionary<string, object>
{
    { "key 1", "value 1" },
    { "key 2", 123 }
};
var dictJson = JsonConvert.SerializeObject(dict); // yields {"key 1":"value 1","key 2":123}

var keyValuePair = dict.FirstOrDefault();
var keyValuePairJson = JsonConvert.SerializeObject(keyValuePair); // yields {"Key":"key 1","Value":"value 1"}

第一個問題是,為什么字典的第一個元素的 json 是KeyValuePair<TKey, TValue> ,與Dictionary<TKey, TValue>的 json 不同?

第二個問題是,如何實現與序列化字典類似的 json 但只有一個項目而不是擴展集合? 我的目標是擁有一個類似於下面的類,但不會將KeyValue作為序列化 json 中的屬性。

public class Foo
{
    public KeyValuePair<string, object> Pair { get; set; }
}

為什么字典的第一個元素的 json 是KeyValuePair<TKey, TValue> ,與Dictionary<TKey, TValue>的 json 不同?

字典和鍵值對是非常不同的東西。 字典不僅僅是鍵值對的集合。 當然,這是對字典的一種看法,但如果說字典就是那樣,那就大錯特錯了。

更具體地說,NewtonsoftJson 中有一個JsonConverter ,專門將KeyValuePair轉換為 JSON 的形式:

{ "Key": ..., "Value": ... }

KeyValuePairConverter

請注意,此表單將鍵和值都轉換為 JSON,這很可能是您將“鍵值”轉換為 JSON 時想要的。 將此與字典轉換器在字典的鍵不是字符串時所做的比較 - 它只是調用ToString使其成為字符串:(

如何實現與序列化字典類似的 json 但只有一個項目而不是擴展集合?

你可以像這樣寫一個JsonConverter

public class KeyValuePairObjectConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);

        if (t.Type != JTokenType.Object)
        {
            t.WriteTo(writer);
        }
        else
        {
            JObject o = (JObject)t;
            string key = o.Value<string>("Key");
            var val = o["Value"];
            writer.WriteStartObject();
            writer.WritePropertyName(key);
            val.WriteTo(writer);
            writer.WriteEndObject();
        }
    }

    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
        => throw new NotImplementedException();

    public override bool CanRead => false;
    public override bool CanConvert(Type t)
    {
        if (t.IsValueType && t.IsGenericType)
        {
            return (t.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)) &&
                    t.GetGenericArguments()[0] == typeof(string);
        }

        return false;
    }
}

用法:

public class Foo
{
    [JsonConverter(typeof(KeyValuePairObjectConverter))]
    public KeyValuePair<string, object> Pair { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM