1. <tfoot id='RGbJx'></tfoot>
    <i id='RGbJx'><tr id='RGbJx'><dt id='RGbJx'><q id='RGbJx'><span id='RGbJx'><b id='RGbJx'><form id='RGbJx'><ins id='RGbJx'></ins><ul id='RGbJx'></ul><sub id='RGbJx'></sub></form><legend id='RGbJx'></legend><bdo id='RGbJx'><pre id='RGbJx'><center id='RGbJx'></center></pre></bdo></b><th id='RGbJx'></th></span></q></dt></tr></i><div id='RGbJx'><tfoot id='RGbJx'></tfoot><dl id='RGbJx'><fieldset id='RGbJx'></fieldset></dl></div>
    <legend id='RGbJx'><style id='RGbJx'><dir id='RGbJx'><q id='RGbJx'></q></dir></style></legend>

      <bdo id='RGbJx'></bdo><ul id='RGbJx'></ul>

      <small id='RGbJx'></small><noframes id='RGbJx'>

      Newtonsoft Json 将字典反序列化为来自 DataContractJs

      时间:2023-08-24

        <legend id='Q3dtj'><style id='Q3dtj'><dir id='Q3dtj'><q id='Q3dtj'></q></dir></style></legend>
      1. <i id='Q3dtj'><tr id='Q3dtj'><dt id='Q3dtj'><q id='Q3dtj'><span id='Q3dtj'><b id='Q3dtj'><form id='Q3dtj'><ins id='Q3dtj'></ins><ul id='Q3dtj'></ul><sub id='Q3dtj'></sub></form><legend id='Q3dtj'></legend><bdo id='Q3dtj'><pre id='Q3dtj'><center id='Q3dtj'></center></pre></bdo></b><th id='Q3dtj'></th></span></q></dt></tr></i><div id='Q3dtj'><tfoot id='Q3dtj'></tfoot><dl id='Q3dtj'><fieldset id='Q3dtj'></fieldset></dl></div>
        • <bdo id='Q3dtj'></bdo><ul id='Q3dtj'></ul>
          • <tfoot id='Q3dtj'></tfoot>

              <tbody id='Q3dtj'></tbody>

            • <small id='Q3dtj'></small><noframes id='Q3dtj'>

              1. 本文介绍了Newtonsoft Json 将字典反序列化为来自 DataContractJsonSerializer 的键/值列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                我有一个使用 DataContractJsonSerializer 序列化到存储的字典,我想使用 Newtonsoft.Json 对其进行反序列化.

                I have a dictionary serialized to storage with DataContractJsonSerializer which I would like to deserialize with Newtonsoft.Json.

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

                The DataContractJsonSerializer has serialized the Dictionary to a list of Key/Value pairs:

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

                我可以为 JsonConvert.DeserializeObject<>() 提供什么很酷的选项,使其支持该数据格式和来自 Newtonsoft.Json 的格式?

                Is there any cool options I can give the JsonConvert.DeserializeObject<>() that will make it support both that data format and the format from Newtonsoft.Json?

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

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

                Is the pretty format Newtonsoft.Json creates, and I would like to be able to read both the old DataContract format and the new Newtonsoft format in a transition period.

                简化示例:

                    //[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":"Val1"},{"Key":"Key2","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"]);
                    }
                

                推荐答案

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

                You could use a custom converter for this, depending on what token the dictionary starts with, deserialize it JSON.NET's default way, or deserialize it into an array and then turn that array into a 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; } 
                    }
                }
                

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

                Then, you can decorate the Dict property in the Data class with a JsonConverter attribute:

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

                然后反序列化两个字符串应该按预期工作.

                Then deserializing both strings should work as expected.

                这篇关于Newtonsoft Json 将字典反序列化为来自 DataContractJsonSerializer 的键/值列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:Newtonsoft.json 程序集包版本不匹配 下一篇:如何使用 JSON.NET 序列化静态或常量成员变量?

                相关文章

                最新文章

              2. <small id='wlViF'></small><noframes id='wlViF'>

                  <bdo id='wlViF'></bdo><ul id='wlViF'></ul>

                  <tfoot id='wlViF'></tfoot>

                    <i id='wlViF'><tr id='wlViF'><dt id='wlViF'><q id='wlViF'><span id='wlViF'><b id='wlViF'><form id='wlViF'><ins id='wlViF'></ins><ul id='wlViF'></ul><sub id='wlViF'></sub></form><legend id='wlViF'></legend><bdo id='wlViF'><pre id='wlViF'><center id='wlViF'></center></pre></bdo></b><th id='wlViF'></th></span></q></dt></tr></i><div id='wlViF'><tfoot id='wlViF'></tfoot><dl id='wlViF'><fieldset id='wlViF'></fieldset></dl></div>
                    <legend id='wlViF'><style id='wlViF'><dir id='wlViF'><q id='wlViF'></q></dir></style></legend>