如何使用包含“原始”JSON的字符串成员序列化和反序列化类型,而无需在进程中转义JSON

我想将JSON反序列化为Object但我不想反序列化嵌套的JSON,嵌套的嵌套JSON应转换为JSON列表(请检查“ 我的预期输出 ”以获得清晰的想法)…

//假设我有以下JSON数据,这里我有“地址”实体的嵌套JSON

String jsonEmployees = "{"Employees": [{"EmpId":1, "EmpName":"ABC", "Address":[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]}, {"EmpId":2, "EmpName":"XYZ", "Address":[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]}] }" public class Employee { public int EmpId { get; set; } public string EmpName { get; set; } // **Note** : I'm not using List
data type for Address, instead of I want list of address in JSON string public string Address { get; set; } } public class RootObject { public List Employees { get; set; } } var Employees = JsonConvert.DeserializeObject(jsonEmployees);

//我的预期输出

 Employees[0].EmpId = 1; Employees[0].EmpName = "ABC"; Employees[0].Address = "[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]"; Employees[1].EmpId = 2; Employees[1].EmpName = "XYZ"; Employees[1].Address = "[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]"; 

请建议我解决这个问题的最佳方法……

您的问题是, 如何使用包含“原始”JSON的string成员序列化和反序列化类型,而无需在进程中转义JSON?

这可以通过使用JsonWriter.WriteRawValue()JRaw.Create()读取和写入原始JSON的自定义JsonConverter来完成:

 public class RawConverter : JsonConverter { public override bool CanConvert(Type objectType) { throw new NotImplementedException(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; var raw = JRaw.Create(reader); return raw.ToString(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var s = (string)value; writer.WriteRawValue(s); } } 

然后将其应用于您的类型,如下所示:

 public class Employee { public int EmpId { get; set; } public string EmpName { get; set; } // **Note** : I'm not using List
data type for Address, instead of I want list of address in JSON string [JsonConverter(typeof(RawConverter))] public string Address { get; set; } } public class RootObject { public List Employees { get; set; } }

样品小提琴 。

请注意,原始JSON字符串必须表示有效的JSON。 如果没有,那么创建的JSON将是不可读的。 如果要保证JSON文字有效,可以在内部将JSON保持在解析状态:

 public class Employee { public int EmpId { get; set; } public string EmpName { get; set; } [JsonProperty("Address")] JToken AddressToken { get; set; } [JsonIgnore] public string Address { get { if (AddressToken == null) return null; return AddressToken.ToString(Formatting.Indented); // Or Formatting.None if you prefer } set { if (value == null) AddressToken = null; else // Throw an exception if value is not valid JSON. AddressToken = JToken.Parse(value); } } } 

此实现不需要转换器。

我想你必须重建你的雇员名单:

  RootObject Employees = JsonConvert.DeserializeObject(jsonEmployees); List EmployeesNew = new List(); foreach (var item in Employees.Employees) { string StringAddress = JsonConvert.SerializeObject(item.Address, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); EmployeesNew.Add(new Employee { EmpId = item.EmpId, EmpName = item.EmpName, AddressString = StringAddress }); } 

你的class:

  public class Employee { public int EmpId { get; set; } public string EmpName { get; set; } // **Note** : I'm not using List
data type for Address, instead of I want list of address in JSON string public List Address { get; set; } public string AddressString { get; set; } } public class RootObject { public List Employees { get; set; } } public class AddressItems { public int AddressId { get; set; } public string Address { get; set; } }

在JSON中,花括号{}是对象的符号,方括号[]是数组。

只要您的数组封装在大括号中,您就必须使用另一个包含对象。 如果你可以摆脱{"Employees":前缀和}后缀,你应该能够直接将JSON转换为员工列表。

编辑:对不起,我不明白这个问题。

根据您是否可以控制JSON,执行您想要的操作要么非常简单,要么非常困难。

如果你可以控制JSON,你需要做的只是在地址值周围添加单引号,所以它看起来像这样:

 [{"EmpId":1, "EmpName":"ABC", "Address":'[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]'}, 

就是这样! 现在序列化器将它转换为字符串。

如果你不能,你必须自己反序列化JSON,令牌令牌。 或者,您可以执行解决方法,创建相应的地址类,并让序列化程序转换为它。 然后添加计算属性并使用序列化程序将地址反序列化回JSON。
(丑陋,我知道,但实施起来要快得多)。