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.)

+3


source to share


2 answers


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);

      

+2


source


Administrator is a string, UserGroup is an object, so this is a type mismatch. Valid JSON for the scenario outlined in your code:



{
    "Code": "Admin",
    "Groups":
    [
        {
            "Code":"Administrator"
        },
        {
            "Code":"Superuser"
        },
        {
            "Code":"User"
        }
    ]
}

      

0


source







All Articles