json.net 相关问题

Json.NET(也称为Newtonsoft.Json)是一种流行的.NET高性能JSON框架。

如何加载具有自定义类型和自定义类型列表的字典

我正在开发一个统一项目,您可以在其中保存具有自定义类型 GraphNode 的键的字典,并且每个键的值是相同类型 GraphNode Dictionary 的列表 我正在开发一个统一项目,您可以在其中保存具有自定义类型 GraphNode 的键的字典,并且每个键的值都是相同类型 GraphNode 的列表Dictionary<GraphNode, List<GraphNode>>。我正在使用 NewtonSoft 库将 json 从对象转换为 json 文本以及从文本转换为对象。 游戏数据脚本: using System; using System.Collections.Generic; [Serializable] public class GameData { public Dictionary<GraphNode, List<GraphNode>> allGraphNodes; public GameData() { allGraphNodes = new Dictionary<GraphNode, List<GraphNode>>(); } } GraphNode 类: public class GraphNode { public enum Type { entrance = 0, enemy = 1, hub = 2, shop = 3, boss = 4 } public Type type; public GraphNode(Type type2) { SetType(type2); } public void SetType(Type type2) { type = type2; } } 我在stackoverflow上尝试了类似的例子,但它不起作用,这是为了保存: public void Save(GameData data) { string text = Path.Combine(dataDirPath, dataFileName); try { Directory.CreateDirectory(Path.GetDirectoryName(text)); string text3 = JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple }); if (useEncryption) { text3 = EncryptDecrypt(text3); } using FileStream stream = new FileStream(text, FileMode.Create); using StreamWriter streamWriter = new StreamWriter(stream); streamWriter.Write(text3); } catch (Exception ex) { Debug.LogError("Error" + text + "\n" + ex); } } 保存的字典示例如下所示: { "$type": "GameData, Assembly-CSharp", "allGraphNodes": { "$type": "System.Collections.Generic.Dictionary`2[[GraphNode, Assembly-CSharp],[System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib]], mscorlib", "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 1 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 0 }, { "$type": "GraphNode, Assembly-CSharp", "type": 3 }, { "$type": "GraphNode, Assembly-CSharp", "type": 1 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 2 }, { "$type": "GraphNode, Assembly-CSharp", "type": 1 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 1 }, { "$type": "GraphNode, Assembly-CSharp", "type": 1 }, { "$type": "GraphNode, Assembly-CSharp", "type": 1 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 3 }, { "$type": "GraphNode, Assembly-CSharp", "type": 2 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 1 }, { "$type": "GraphNode, Assembly-CSharp", "type": 1 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 2 }, { "$type": "GraphNode, Assembly-CSharp", "type": 4 }, { "$type": "GraphNode, Assembly-CSharp", "type": 2 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 1 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 1 }, { "$type": "GraphNode, Assembly-CSharp", "type": 4 }, { "$type": "GraphNode, Assembly-CSharp", "type": 1 }, { "$type": "GraphNode, Assembly-CSharp", "type": 3 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 2 }, { "$type": "GraphNode, Assembly-CSharp", "type": 3 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 2 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 2 }, { "$type": "GraphNode, Assembly-CSharp", "type": 3 } ] }, "GraphNode": { "$type": "System.Collections.Generic.List`1[[GraphNode, Assembly-CSharp]], mscorlib", "$values": [ { "$type": "GraphNode, Assembly-CSharp", "type": 1 }, { "$type": "GraphNode, Assembly-CSharp", "type": 4 } ] } } } 这用于加载(出现错误的部分被标记为重要行): public GameData LoadLayout() { string text = Path.Combine(dataDirPath, dataFileName); GameData result = null; if (File.Exists(text)) { try { string text2 = ""; using (FileStream stream = new FileStream(text, FileMode.Open)) { using StreamReader streamReader = new StreamReader(stream); text2 = streamReader.ReadToEnd(); Debug.Log(text2); } if (useEncryption) { text2 = EncryptDecrypt(text2); } result = JsonConvert.DeserializeObject<GameData>(text2, new JsonSerializerSettings //important line { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple }); return result; } catch (Exception ex) { Debug.LogError("Error" + text + "\n" + ex); return result; } } return result; } 错误打印: Newtonsoft.Json.JsonSerializationException:无法将字符串“GraphNode”转换为字典键类型“GraphNode”。创建一个 TypeConverter 将字符串转换为键类型对象。路径“allGraphNodes.GraphNode”,第 5 行,位置 16。 ---> Newtonsoft.Json.JsonSerializationException:将值“GraphNode”转换为类型“GraphNode”时出错。路径“allGraphNodes.GraphNode”,第 5 行,位置 16。 ---> System.ArgumentException:无法从 System.String 转换或转换为 GraphNode。 您遇到几个问题: 您的字典具有复杂的键,但是,正如文档中所述,由于 Json.NET 默认将字典序列化为 JSON 对象,因此序列化仅适用于可转换为字符串的键。 因此,您需要将 allGraphNodes 序列化为数组。 将字典序列化为(键值对)数组中显示的方法有多种,但最简单的可能是使用代理数组属性序列化字典。 字典中的 List<GraphNode> 值可能引用字典中的其他键。要在序列化过程中保留这些引用,您需要在启用引用保留的情况下进行序列化。 不幸的是,引用保存不适用于参数化构造函数,因此GraphNode将需要一个无参数构造函数。只要标上[JsonConstructor]就可以私密。 您正在使用TypeNameHandling.All进行序列化,但是正如文档中所述,这会带来安全风险。有关详细信息,请参阅 Newtonsoft Json 中的 TypeNameHandling 警告 和 由于 Json.Net TypeNameHandling auto?,外部 json 容易受到攻击?它还可能导致 JSON 文件出现不必要的膨胀。 您当前的数据模型不需要此设置,因为它不使用多态性。如果您确实认为有必要,请考虑编写自定义的序列化绑定器。 将所有这些放在一起,如果您按如下方式修改数据模型: [Serializable] public class GameData { [JsonIgnore] public Dictionary<GraphNode, List<GraphNode>> allGraphNodes; public GameData() { allGraphNodes = new Dictionary<GraphNode, List<GraphNode>>(); } [JsonProperty("allGraphNodes")] KeyValuePair<GraphNode, List<GraphNode>> [] allGraphNodeArray { get { return allGraphNodes?.ToArray(); } set { allGraphNodes = allGraphNodes ?? new Dictionary<GraphNode, List<GraphNode>>(); if (value != null) foreach (var pair in value) allGraphNodes.Add(pair.Key, pair.Value); } } } [Serializable] [JsonObject(IsReference = true)] // Forces all instances to be serialized with reference preservation public class GraphNode { public enum Type { entrance = 0, enemy = 1, hub = 2, shop = 3, boss = 4 } public Type type; [JsonConstructor] // Constructor for serialization. GraphNode() { } public GraphNode(Type type) { SetType(type); } public void SetType(Type type) { this.type = type; } } 您将能够按如下方式进行序列化: var settings = new JsonSerializerSettings { // Add any settings as required, e.g. // Converters = { new StringEnumConverter() }, }; var json1 = JsonConvert.SerializeObject(gameData1, settings); var gameData2 = JsonConvert.DeserializeObject<GameData>(json1, settings); 演示小提琴在这里。

回答 1 投票 0

追加多个 JSON 数组并创建一个新的合并 JSON 数组

在文件路径中,我有一些 JSON 文件,我正在尝试使用 Newtonsoft.Json 将它们合并到一个文件中。 JSON1: [ { “姓名”:“姓名1”, 「工资」:

回答 2 投票 0

如何反序列化 JSON(无法将当前 JSON 对象(例如 {""name"":""value""})反序列化为类型 'System.Collections.Generic.List`1)

序列化 JSON 时,如果显示类似这样的错误。 (无法将当前 JSON 对象(例如 {""name"":""value""})反序列化为类型 'System.Collecti...

回答 1 投票 0

Azure 函数:OpenApi/swagger 忽略 System.Text.Json.Serialization.JsonPropertyName 属性

我有一个由http触发的简单的azure函数: [OpenApiOperation(操作Id: "GetX", 标签: new[] { nameof(GetXHttpTrigger) })] [OpenApiParameter(名称: "id", In =

回答 1 投票 0

使用 JSON.net 获取 JToken 的名称/密钥

我有一些看起来像这样的 JSON [ { “移动网站内容”:{ "文化": "en_au", “钥匙”: [ “密钥名称1” ] } }, { “页面内容”:{ 《文化》:“e...

回答 7 投票 0

如何在.NET 6.0中使用最小API配置NewtonsoftJson

我有一个具有最小API的net6.0项目,我想使用NetwtonsoftJson而不是内置的System.Text.Json库进行序列化和反序列化。 目前我有这个配置...

回答 1 投票 0

Newtonsoft Json.NET 有关必需和 NullValueHandling 设置的参考

我没有找到一个很好的参考表来解释 Newtonsoft Json.NET 对于必需和 NullValueHandling 设置的各种组合的确切序列化和反序列化行为...

回答 1 投票 0

如何实现条件自定义Json转换器隐藏属性

我在.Net中有一个REST API,它返回以下对象: 公开课 MyDto { 公共字符串名称{get;放;} 公共 int 年龄 {get;放;} 公共字符串联系号码{get;放;} } 我想要

回答 1 投票 0

Json.Net (8.0) 在 Mono 4.5 Mac 上创建 StringEnumConverter 时出错

我无法理解 Mac 上的 Json.Net 遇到的问题。 我正在尝试序列化/反序列化对象,如下所示。 该代码在 Windows 上运行没有问题,但生成...

回答 5 投票 0

Newtonsoft.Json 的 JsonPath 实现中的赋值

我有一个像这样的Json: { “选项”: [ { “价格”:217, “数量”:2 }, { “价格”:63, ...

回答 1 投票 0

从 JsonConvert.SerializeXNode 返回具有正确类型的 json

var 测试 = 新 { TestStr = "测试", 测试编号 = 123, TestDate = 新的 DateTime(1986, 1, 13, 17, 50, 31), 测试布尔 = true ...

回答 2 投票 0

如果json反序列化过程中出现错误,如何忽略数据行

我需要一种方法来忽略以 JSON 形式提供给 newtonsoft JsonCovert 的大型列表中 JsonProperty 失败(引发错误)的行/项目。 目前使用这个问题(和答案)作为

回答 1 投票 0

Newtonsoft JSON 反序列化多个对象数据

我的json数据如下 { “频道数据”:{ “pva:gpt-反馈”:{ “summarizationOpenAIResponse”:{ “结果”:{ ”

回答 1 投票 0

无法在C#中对JSON文件进行操作

我有图书馆申请,可以注册为新用户,添加一些书籍,借阅和存放。 我的 JSON 文件有问题,因为当我从中获取数据时,我无法...

回答 1 投票 0

从json结构中获取特定值

我有这个json: { “测试”: { “身份证”:107537, “名称”:“测试”, “个人资料图标Id”:785, ”

回答 4 投票 0

从 JsonReader 读取 JObject 时出错。当前 JsonReader 项不是对象:StartArray。路径

我正在开发一个涉及位置的Windows Phone 8.1应用程序。我正在从 API 接收 Json 数据。我的 API 返回的数据如下所示: [{ “国家”:“印度”, "city": "古商城路...

回答 6 投票 0

序列化的 JSON 不是反序列化

我有一些 JSON 代码嵌入到我使用 JsonConvert 的 JSON 对象中。 SerializeObject() 来正确地为自己转义,然后我立即尝试 JsonConvert.DeserializeObject() 并得到一个 e...

回答 1 投票 0

JSON.NET 将对象反序列化为对象列表

我正在尝试使用 JSON.NET 库将对象反序列化为对象列表。我的 json 文件是: [ { “id”:1, “名称”:“波兹塔”, “描述”:“说明”, “纬度”:52.25197, “经度”:...

回答 4 投票 0

将 JArray 转换为列表,仅保留一个嵌套的 JToken

我有一个如下所示的 JArray: [ { “1”:“A”, “2”:“B”, “3”:{ “5”:“D”, ...

回答 1 投票 0

ASP.NET Core OData响应json序列化空值处理

考虑将数据公开为 OData 的两个端点。 ODataController 中的第一个: 私有静态只读字符串[]摘要=新[] { “冰冷”、“振奋”、“寒冷”……

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.