如何使用包含“原始”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。
(丑陋,我知道,但实施起来要快得多)。