使用 JSON 序列化和反序列化字典

Serializing and DeSerializing a Dictionary with JSON

提问人:TheMostEpic 提问时间:1/2/2020 最后编辑:Adrian MoleTheMostEpic 更新时间:1/2/2020 访问量:208

问:

我想序列化一个包含不同种类对象(动态)的字典并将其保存到一个文件中。加载文件时,软件需要再次将数据反序列化为 Dictionary 并设置对象引用。当我尝试设置对象时,它给了我错误:

无法隐式将类型“Newtonsoft.Json.Linq.JObject”转换为 'PartyCreator.Member'。

DeSerialized Dictionary似乎正在工作,例如,我可以访问member1属性,但无法将对象引用到从我自己的Member类创建的已经存在的对象member1。loadedObjects["member1"].Name

// Serializing the Dictionary           
Dictionary<string, dynamic> savedObjects = new Dictionary<string, dynamic>();

savedObjects.Add("member1", member1);
savedObjects.Add("member2", member2);
savedObjects.Add("member3", member3);
savedObjects.Add("member4", member4);   

var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver() };
var saveData = JsonConvert.SerializeObject(savedObjects, settings);

// DeSerializing the Dictionary
Dictionary<string, dynamic> loadedObjects = new Dictionary<string, dynamic>();
loadedObjects = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(saveData);

member1 = loadedObjects["member1"]; // Giving an error: Cannot implicitly convert type 'Newtonsoft.Json.Linq.JObject' to 'PartyCreator.Member'

// These are the settings i'm using with Json Serializer
public class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                    .Select(p => base.CreateProperty(p, memberSerialization))
                    .Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                    .Select(f => base.CreateProperty(f, memberSerialization)))
                    .Where(p => !p.PropertyName.Contains("k__BackingField"))
                    .ToList();
            props.ForEach(p => { p.Writable = true; p.Readable = true; });
            return props;
    }
}
C# JSON 字典 json.net

评论

0赞 Pavel Anikhouski 1/2/2020
您可以通过键访问字典中的值,例如loadedObjects["member1"].Value<PartyCreator.Member>();
0赞 Bryan Dellinger 1/2/2020
查看亚当·弗里曼 (Adam Freemen) 的摘录 github.com/Apress/pro-asp.net-core-mvc-2/blob/master/...
1赞 dbc 1/2/2020
JSON 不存储 c# 类型信息,因此当您序列化为 JSON 时,对象的实际类型将丢失。要存储类型信息,请按此答案中所示进行设置。如何使用 Newtonsoft 将 JSON 反序列化为 IEnumerable<BaseType> JSON.NET 也讨论了这个问题,以及如何在 JSON.NET 中实现自定义 JsonConverter 以反序列化基类对象的列表?dynamicTypeNameHandling.Auto
1赞 dbc 1/2/2020
但是,使用会给您的应用带来安全漏洞,请参阅 Newtonsoft Json 中的 TypeNameHandling 警告和外部 json 易受攻击,因为 TypeNameHandling auto?Json.NetTypeNameHandling

答: 暂无答案