程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Newtonsoft Json Deserialize Dictionary作为DataContractJsonSerializer的键/值列表大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Newtonsoft Json Deserialize Dictionary作为DataContractJsonserializer的键/值列表?

开发过程中遇到Newtonsoft Json Deserialize Dictionary作为DataContractJsonserializer的键/值列表的问题如何解决?下面主要结合日常开发的经验,给出你关于Newtonsoft Json Deserialize Dictionary作为DataContractJsonserializer的键/值列表的解决方法建议,希望对你解决Newtonsoft Json Deserialize Dictionary作为DataContractJsonserializer的键/值列表有所启发或帮助;

您可以为此使用自定义转换器,具体取决于字典以什么令牌开头,将其反序列化为JsON.NET的默认方式,或将其反序列化为数组,然后将该数组转换为Dictionary

public class DictionaryConverter : JsonConverter
{
    public overrIDe object ReadJson(
        JsonReader reader,
        Type objectType,
        object exisTingValue,
        Jsonserializer serializer)
    {
        IDictionary<String, String> result;

        if (reader.TokenType == JsonToken.StartArray)
        {
            JArray legacyArray = (JArray)JArray.ReadFrom(reader);

            result = legacyArray.ToDictionary(
                el => el["Key"].ToString(),
                el => el["Value"].ToString());
        }
        else 
        {
            result = 
                (IDictionary<String, String>)
                    serializer.Deserialize(reader, typeof(IDictionary<String, String>));
        }

        return result;
    }

    public overrIDe voID WriteJson(
        JsonWriter writer, object value, Jsonserializer serializer)
    {
        throw new NotImplementedException();
    }

    public overrIDe bool CanConvert(Type objectTypE)
    {
        return typeof(IDictionary<String, String>).IsAssignableFrom(objectTypE);
    }

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

然后,您可以使用Dict属性装饰Data类中的JsonConverter属性:

public sealed class Data
{
    [JsonConverter(typeof(DictionaryConverter))]
    public IDictionary<String, String> Dict { get; set; }
}

然后对两个字符串进行反序列化应能按预期工作。

解决方法

我有一个序列化到DataContractJsonserializer的字典,我想与Newtonsoft.Json反序列化。

DataContractJsonserializer已将Dictionary序列化为键/值对的列表:

{"Dict":[{"Key":"key1","Value":"Val1"},{"Key":"Key2","Value":"Val2"}]}

我可以提供任何很酷的选择JsonConvert.DeserializeObject<>(),使其同时支持该数据格式和Newtonsoft.Json的格式吗?

{"Dict":{"key1":"Val1","Key2":"Val2"}}

是Newtonsoft.Json创建的漂亮格式,我希望能够在过渡期内读取旧的DataContract格式和新的Newtonsoft格式。

简化示例:

    //[JsonArray]
    public sealed class Data
    {
        public IDictionary<String,String> Dict { get; set; }
    }

    [TestMethod]
    public void TestserializeDataContractDeserializeNewtonsoftDictionary()
    {
        var d = new Data
        {
            Dict = new Dictionary<String,String>
            {
                {"key1","Val1"},{"Key2","Val2"},}
        };

        var oldJson = String.Empty;
        var formatter = new DataContractJsonserializer(typeof (Data));
        using (var stream = new MemoryStream())
        {
            formatter.WriteObject(stream,d);
            oldJson = Encoding.UTF8.GetString(stream.ToArray());
        }

        var newJson = JsonConvert.serializeObject(d);
        // [JsonArray] on Data class gives:
        //
        // System.InvalidCastException: Unable to cast object of type 'Data' to type 'System.Collections.IEnumerable'.

        Console.WriteLine(oldJson);
        // This is tha data I have in storage and want to deserialize with Newtonsoft.Json,an array of Key/value pairs
        // {"Dict":[{"Key":"key1","Value":"Val2"}]}

        Console.WriteLine(newJson);
        // This is what Newtonsoft.Json generates and should also be supported:
        // {"Dict":{"key1":"Val1","Key2":"Val2"}}

        var d2 = JsonConvert.DeserializeObject<Data>(newJson);
        Assert.AreEqual("Val1",d2.Dict["key1"]);
        Assert.AreEqual("Val2",d2.Dict["Key2"]);

        var d3 = JsonConvert.DeserializeObject<Data>(oldJson);
        // Newtonsoft.Json.JsonserializationException: CAnnot deserialize the current JSON array (e.g. [1,2,3]) into 
        // type 'System.Collections.Generic.IDictionary`2[System.String,System.String]' because the type requires a JSON 
        // object (e.g. {"name":"value"}) to deserialize correctly.
        //
        // To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type
        // to an array or a type that implements a collection interface (e.g. ICollection,IList) like List<T> that can be 
        // deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from
        // a JSON array.
        //
        // Path 'Dict',line 1,position 9.

        Assert.AreEqual("Val1",d3.Dict["key1"]);
        Assert.AreEqual("Val2",d3.Dict["Key2"]);
    }

大佬总结

以上是大佬教程为你收集整理的Newtonsoft Json Deserialize Dictionary作为DataContractJsonSerializer的键/值列表全部内容,希望文章能够帮你解决Newtonsoft Json Deserialize Dictionary作为DataContractJsonSerializer的键/值列表所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。