Reputation: 148
I am starting to think I need to write a custom converter in Json.net because so far the regular converter is not cutting it. I have a class Game
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;
}
That Serializes to the correct Json, but won't deserialize correctly. the Json looks like this:
{
"Edition": 1,
"Name": "Regular",
"Date": "2016",
"NameType": "Regular",
"Questions": [
{
"QuestionNumber": "1",
"Round": 1,
"Body": "1. A couple paragraphs",
"Answer": " answers"
},
]
}
But when deserialized, it comes out as:
Date"2016", Edition "1", Name "None", NameType "None", Questions null
did I do something wrong in deserializing like this:
Game g = JsonConvert.DeserializeObject<Game>(File.ReadAllText(path));
or is this a situation which warrants writing a custom serializer?
I have yet to find a question currently answered that deals with something like this bug I have hit, and according to the documentation on Json.net most of the weird edge cases that need a custom serializer are non-IEnumerables and DateTimes.
Upvotes: 1
Views: 71
Reputation: 116785
It looks as though you are trying to create a class with some immutable properties, namely Edition
, Date
, NameType
. Furthermore, one of then, NameType
, needs a JsonConverter
applied to be serialized properly by Json.NET. You can serialize and deserialize such a class by giving it one single constructor with the necessary properties passed in as arguments provided the argument names are the same as the c# property names, modulo case. You can apply the attribute [JsonConverter(typeof(StringEnumConverter))]
to the appropriate argument as well as to the corresponding property, however if it is not applied the converter from the corresponding property will be used as long as the property and parameter have identical declared types.
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
}
Sample fiddle.
If your class has more than one constructor, mark the one that has all the required immutable properties with [JsonConstructor]
, e.g.:
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;
}
Upvotes: 1