Several options are available. You can have a custom JsonConverter and serialize it manually. Since, at the time of this writing, fero has provided an answer based on this, I will give you an alternative requiring two surrogate classes:
public class JsonUser { public string Name { get; set; } public Dictionary<int, JsonRole> Roles { get; set; } } public class JsonRole { public string Name { get; set; } }
And in your Role class:
public static implicit operator User(JsonUser user) { return new User { Name = user.Name, Roles = user.Roles .Select(kvp => new Role { Id = kvp.Key, Name = kvp.Value.Name}) .ToArray() }; }
What can be used as follows:
User jsonUser = JsonConvert.DeserializeObject<JsonUser>(json);
Now this is done by creating an intermediate object and is probably not suitable for most cases.
For completeness, I will include my version of the JsonConverter solution:
public class UserRolesConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof (Role[]); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return serializer.Deserialize<JObject>(reader) .Properties() .Select(p => new Role { Id = Int32.Parse(p.Name), Name = (string) p.Value["name"] }) .ToArray(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } public class User { public string Name { get; set; } [JsonConverter(typeof(UserRolesConverter))] public Role[] Roles { get; set; } } var jsonUser = JsonConvert.DeserializeObject<User>(json);
source share