C# 如何使用JSON.NET序列化POCO';s作为字符串列表,以减小大小?
我有这样一个简单的POCO:C# 如何使用JSON.NET序列化POCO';s作为字符串列表,以减小大小?,c#,serialization,json.net,C#,Serialization,Json.net,我有这样一个简单的POCO: public class Edit { ... } public class CharInsert : Edit { public int ParagraphIndex { get; set; } public int CharacterIndex { get; set; } public char Character { get; set; } } 在JSON中序列化如下(注意,由
public class Edit { ... }
public class CharInsert : Edit
{
public int ParagraphIndex { get; set; }
public int CharacterIndex { get; set; }
public char Character { get; set; }
}
在JSON中序列化如下(注意,由于继承,我正在记录对象类型):
但这会占用大量空间来存储相当少的数据。我有很多,所以我需要更紧凑一些
我制作了一个定制的JsonConverter
,因此它将改为如下序列化:
"CharInsert|7|15|e"
当我坚持列出这些内容时,我得到:
[
"CharInsert|7|12|Z",
"CharInsert|7|13|w",
"CharInsert|7|14|i",
"CharInsert|7|15|e",
]
但是,当我尝试对该列表进行反序列化时,会出现以下错误:
'将值“CharInsert | 7 | 12 | Z”转换为类型“MyNamespace.Edit”时出错'
我想这是因为实际对象是Edit类型的子类,它不知道是哪一个,因为它不知道如何解析字符串。我如何实现它,以便它能够解析字符串,解析其中包含的类型名,然后创建所需的对象类型?我已经解决了这个问题。问题是,如果序列化字符串中没有类型信息(
“CharInsert | 7 | 15 | e”
),反序列化程序不知道要调用哪个派生类
因此,我为基本的Edit
类型制作了一个JsonConverter
,它知道如何解析字符串并从该字符串创建和返回and对象:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//get the persisted value
var s = reader.Value?.ToString();
var fields = s.Split('|');
var typeName = ...get the type name from the field
var type = Type.GetType(typeName);
//create an object from the remaining fields using the ctor(string value) that
//each subclass must have
return System.Activator.CreateInstance(type, new object[] { fields.Skip(1).ToJoinedString("|") });
}
一种替代自定义转换器的方法,考虑使用<代码> [jsNealStices(PrimeNoTy= =)] < /C> >缩短JSON属性名称,这应该减少空间,而不必担心自定义转换器。
public class CharInsert : Edit
{
[JsonProperty(PropertyName = "p")]
public int ParagraphIndex { get; set; }
[JsonProperty(PropertyName = "i")]
public int CharacterIndex { get; set; }
[JsonProperty(PropertyName = "c")]
public char Character { get; set; }
}
我会认真考虑改变这种做法,目前的实施非常脆弱和容易出错。假设对象中的字段在序列化和反序列化之间发生了变化?这不是因为序列化程序不知道类型,而是因为
“CharInsert | 7 | 15 | e”
不是有效的JSON对象。默认反序列化程序无法在非JSONI的CharInsert
对象中填充属性。我不知道如果不使用JSON,为什么还要使用JSON.Net。@Dmitristoy:更改为什么?更改字段往往会打破传统序列化的平衡。@MindSwipe:数据类型是一个列表,我只想将T序列化为所示的字符串a,以节省大约90%的空间,同时仍然使用JSON作为文件格式。有点像“到Csv”的列表-ed然后将其包装在一个Json对象中,该对象的属性告诉您反序列化应该使用什么Csv配置?为什么不使用BSON或其他比Json更轻量级的格式?
public class CharInsert : Edit
{
[JsonProperty(PropertyName = "p")]
public int ParagraphIndex { get; set; }
[JsonProperty(PropertyName = "i")]
public int CharacterIndex { get; set; }
[JsonProperty(PropertyName = "c")]
public char Character { get; set; }
}