Deserialize List <string> from Json to list <object>
I have the following json line as a sample for my problem:
{
"Code": "Admin",
"Groups":
[
"Administrator",
"Superuser",
"User"
]
}
Also I have a class named User with code like this ...
[JsonObject(MemberSerialization.OptIn)]
public class User
{
public User (string code)
{
this.Code = code;
}
[JsonProperty]
public string Code { get; set; }
[JsonProperty("Groups")]
private List<UserGroup> groups;
public List<UserGroup> Groups
{
if (groups == null)
groups = new List<UserGroup>();
return groups;
}
}
... and a class named UserGroup with - for this example - just a few lines of code:
public class UserGroup
{
public UserGroup (string code)
{
this.Code = code;
// Some code to fill all the other properties, just by knowing the code.
}
public string Code { get; set; }
// More properties
}
Now I want the above JSON string to be deserialized into a user instance and all the strings in the "Groups" array should be deserialized into List<UserGroup>
with instances from each of those strings. Also - conversely - whether the user should be serialized to a JSON string with only the Code property of the contained UserGroups.
I don't deserialize ok but instantiate the user and populate it with this code ...
Newtonsoft.Json.JsonConvert.PopulateObject(jsonString, myUserInstance);
... but if I run the code with the above JSON string, then all I get is the following exception:
Newtonsoft.Json.JsonSerializationException: 'Error converting value "Administrator" to type 'UserGroup'.
My final requirement is that I want to UserGroup
be serialized as an array of strings only if I am serializing User
. When I serialize standalone UserGroup
as root object, it should be serialized normally (with all properties). (For comparison, in Json.Net: Serialize / Deserialize property as value rather than object , object is serialized as string in all situations.)
source to share
You will need to write a converter for UserGroup
Here is a simple converter based on what was described in the question
public class UserGroupJsonConverter : JsonConverter {
public override bool CanConvert(Type objectType) {
return typeof(UserGroup) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
return new UserGroup((string)reader.Value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
writer.WriteValue(((UserGroup)value).Code);
}
}
And then update User
to know about the converter by setting the ItemConverterType
attributeJsonProperty
[JsonObject(MemberSerialization.OptIn)]
public class User {
public User(string code) {
this.Code = code;
}
[JsonProperty]
public string Code { get; set; }
private List<UserGroup> groups;
[JsonProperty("Groups", ItemConverterType = typeof(UserGroupJsonConverter))]
public List<UserGroup> Groups {
get {
if (groups == null)
groups = new List<UserGroup>();
return groups;
}
}
}
This will now enable JSON in the example
{
"Code": "Admin",
"Groups":
[
"Administrator",
"Superuser",
"User"
]
}
to deserialize as desired
var user = JsonConvert.DeserializeObject<User>(json);
and be serialized back to the same format.
var json = JsonConvert.SerializeObject(user);
source to share