Reputation: 549
I have the following json string 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 - only this few code lines:
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, what I want is that the above shown JSON string would be deserialized into an instance of an User and all strings in the "Groups" array should be deserialized into a List<UserGroup>
with instances from each of those strings.
Also - the other way round - should a User be serialized into an JSON string with only the Code property of the contained UserGroups.
I don't deserialize normally but I create an instance of an User and populate it with this code...
Newtonsoft.Json.JsonConvert.PopulateObject(jsonString, myUserInstance);
... but if I run the code with the above shown JSON string all I get is the following exception:
Newtonsoft.Json.JsonSerializationException: 'Error converting value "Administrator" to type 'UserGroup'.
My final requirement is that, I want the UserGroup
to be serialized as an array of strings only if I serialize the User
. When I serialize a UserGroup
standalone as a root object, it should be serialized normally (with all properties). (For comparison, in Json.Net: Serialize/Deserialize property as a value, not as an object the object is serialized as a string in all situations.)
Upvotes: 3
Views: 4303
Reputation: 247333
You are going to have to write a converter for the 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 the User
to be aware of the converter by setting the ItemConverterType
of the JsonProperty
attribute
[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 would now allow for the JSON in the example
{
"Code": "Admin",
"Groups":
[
"Administrator",
"Superuser",
"User"
]
}
to be deserialized as desired
var user = JsonConvert.DeserializeObject<User>(json);
and to be serialized back into the same format.
var json = JsonConvert.SerializeObject(user);
Upvotes: 2
Reputation: 516
Administrator is a string, UserGroup is an object so this is a type mismatch. The valid JSON for the scenario laid out in your code is:
{
"Code": "Admin",
"Groups":
[
{
"Code":"Administrator"
},
{
"Code":"Superuser"
},
{
"Code":"User"
}
]
}
Upvotes: 0