我想将JSON反序列化为Object但我不想反序列化嵌套的JSON,嵌套的嵌套JSON应转换为JSON列表(请检查“我的预期输出”以获得清晰的想法)。 ..
//假设我有以下JSON数据,这里我为“地址”实体
嵌套了JSONString 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<Address> data type for Address, instead of I want list of address in JSON string
public string Address { get; set; }
}
public class RootObject
{
public List<Employee> Employees { get; set; }
}
var Employees = JsonConvert.DeserializeObject<RootObject>(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"}]";
请建议我解决此问题的最佳方法......
答案 0 :(得分:6)
您的问题是,如何使用包含&#34; raw&#34;的string
成员序列化和反序列化类型? JSON,没有在进程中转义JSON?
这可以通过使用custom JsonConverter
和JsonWriter.WriteRawValue()
读取和写入原始JSON的JRaw.Create()
来完成:
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<Address> 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<Employee> Employees { get; set; }
}
示例fiddle。
请注意,原始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);
}
}
}
此实施不需要转换器。
答案 1 :(得分:1)
我认为你必须重建员工名单:
RootObject Employees = JsonConvert.DeserializeObject<RootObject>(jsonEmployees);
List<Employee> EmployeesNew = new List<Employee>();
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 });
}
你的班级:
public class Employee
{
public int EmpId { get; set; }
public string EmpName { get; set; }
// **Note** : I'm not using List<Address> data type for Address, instead of I want list of address in JSON string
public List<AddressItems> Address { get; set; }
public string AddressString { get; set; }
}
public class RootObject
{
public List<Employee> Employees { get; set; }
}
public class AddressItems
{
public int AddressId { get; set; }
public string Address { get; set; }
}
答案 2 :(得分:0)
在JSON中,大括号{}
是对象的符号,方括号[]
用于数组。
只要您的数组封装在大括号中,您就必须使用另一个包含对象。如果您可以删除{"Employees":
前缀和}
后缀,则应该能够直接将JSON转换为员工列表。
根据您是否可以控制JSON,执行您想要的操作非常简单或非常困难。
如果你可以控制JSON,你需要做的只是在地址值周围添加单引号,所以它看起来像这样:
[{"EmpId":1, "EmpName":"ABC", "Address":'[{"AddressId":1, "Address":"Something"},{"AddressId":2, "Address":"Anything"}]'},
就是这样!现在序列化器将它转换为字符串。
如果你不能,你必须自己反序列化JSON,令牌令牌。或者,您可以执行一种解决方法,创建相应的地址类,并让序列化程序转换为它。然后添加一个计算属性并使用序列化程序将地址反序列化为JSON (丑陋,我知道,但实施起来要快得多)。