我开始认为我需要用 Json.net 编写一个自定义转换器,因为到目前为止,常规转换器还没有削减它。我有一个班级游戏
class Game
{
[JsonProperty]
public int Edition { get; private set; }
[JsonProperty]
public string Name
{
get
{
return NameType.ToString();
}
private set
{
name = value;
}
}
[JsonProperty]
public string Date { get; private set; }
[JsonConverter(typeof(StringEnumConverter))]
public GameType NameType { get; private set; } //enum
public List<Question> Questions { get; private set; } //yes, Question is serializable
public Game(string Date, GameType t, int num, List<Question> q)
{
this.Date = Date;
this.NameType = t;
this.Edition = num;
this.Questions = q;
}
序列化为正确的 Json,但不会正确反序列化。Json 看起来像这样:
{
"Edition": 1,
"Name": "Regular",
"Date": "2016",
"NameType": "Regular",
"Questions": [
{
"QuestionNumber": "1",
"Round": 1,
"Body": "1. A couple paragraphs",
"Answer": " answers"
},
]
}
但是当反序列化时,它显示为:
日期"2016",版本"1",名称"无",名称类型"无",问题空
我在这样的反序列化中做错了什么:
Game g = JsonConvert.DeserializeObject<Game>(File.ReadAllText(path));
或者这种情况是否需要编写自定义序列化程序?
我还没有找到一个目前回答的问题来处理我遇到的这个错误,根据 Json.net 文档,大多数需要自定义序列化程序的奇怪边缘情况都是非 IEnumerables 和 DateTimes。
看起来您正在尝试创建一个具有一些不可变属性的类,即 Edition
、 Date
、 NameType
。 此外,其中一个,NameType
,需要应用一个JsonConverter
才能被 Json.NET 正确序列化。 可以通过为此类提供单个构造函数来序列化和反序列化此类,该构造函数具有作为参数传递的必要属性,前提是参数名称与 c# 属性名称相同(模大小写)。 可以将属性[JsonConverter(typeof(StringEnumConverter))]
应用于相应的参数以及相应的属性,但是,如果未应用,则只要属性和参数具有相同的声明类型,就会使用相应属性中的转换器。
class Game
{
public Game(int edition, string date, [JsonConverter(typeof(StringEnumConverter))] GameType nameType)
{
this.Edition = edition;
this.Date = date;
this.NameType = nameType;
this.Questions = new List<Question>();
}
public int Edition { get; private set; }
[JsonIgnore]
public string Name
{
get
{
return NameType.ToString();
}
}
public string Date { get; private set; }
[JsonConverter(typeof(StringEnumConverter))]
public GameType NameType { get; private set; } //enum
public List<Question> Questions { get; private set; } //yes, Question is serializable
}
样品小提琴。
如果你的类有多个构造函数,用 [JsonConstructor]
标记具有所有必需的不可变属性的构造函数,例如:
public Game(int edition, string date, [JsonConverter(typeof(StringEnumConverter))] GameType nameType)
: this(edition, date, nameType, new List<Question>())
{
}
[JsonConstructor]
public Game(int edition, string date, [JsonConverter(typeof(StringEnumConverter))] GameType nameType, List<Question> questions)
{
this.Edition = edition;
this.Date = date;
this.NameType = nameType;
this.Questions = questions;
}