我正在使用Json.NET,我有以下代码。
public class Row
{
[JsonProperty]
public IDictionary<string, object> Cells { get; set; }
}
行和单元格是动态生成的,我有C#动态/Expando功能来创建这些单元格。当Json.NET序列化动态实例时,它会生成我想要的正确Json结构。然而,对于大型数据结构,它会对性能产生不利影响。例如,JsonSerializer在序列化期间非常广泛地调用DynamicObject TryGetMember。因此,我需要一个静态数据结构,这样序列化会更快。synamic Expando对象仍然会创建动态属性,但我希望Json.NET序列化使用静态结构(基于动态结构创建),这样序列化会更快。
Cells字典基于动态结构进行填充,并通过调用JsonConvert,生成如下所示的序列化json结构。
string serializeObject = JsonConvert.SerializeObject(data, Formatting.Indented);
//json输出:
{
"Data": [
{
"Cells": {
"column1": "20",
"column2": "20"
}
},
{
"Cells": {
"column1": "20",
"column2": "20"
}
}
]
}
然而,我绑定到的UI网格需要以下json结构
"Data": [
{
"column1": "20",
"column2": "20"
},
{
"column1": "20",
"column2": "20"
}
]
有没有一种方法可以去除"细胞"并产生如上所述的Json结构?
我查看了JSON.NET帮助文档,但找不到实现这一点的方法。还尝试重写DynamicContractResolver的CreateProperty方法,看看我是否可以更改序列化行为,但我无法这样做
public class DynamicContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(System.Reflection.MemberInfo member, MemberSerialization memberSerialization)
{
if (member.Name == "Cells")
{
//remove the name "Cells" from the serialized structure
}
return base.CreateProperty(member, memberSerialization);
}
}
或者这不是简单的支持?非常感谢任何建议或指示。
找到了一种通过创建自定义转换器来解决这一问题的方法。下面的代码产生了我需要的Json结果。
public class GridJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true; //TODO: more logic check the type before the conversion..
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
var rows = (List<Row>)value;
writer.WriteStartObject();
writer.WritePropertyName("data");
writer.WriteStartArray();
foreach (var row in rows)
{
writer.WriteStartObject();
var cells = row.Cells;
foreach (var cell in cells)
{
writer.WritePropertyName(cell.Key);
writer.WriteValue(cell.Value);
}
writer.WriteEndObject();
}
writer.Flush();
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
//用法示例:
string serializeObject = JsonConvert.SerializeObject
(someData, Formatting.Indented, new GridJsonConverter());