使用非原始属性将对象填充为来自JSON的字符串

问题描述:

我有以下两个示例类。首先是User类...使用非原始属性将对象填充为来自JSON的字符串

public class User : ILoadable 
{ 
    public User(string code) 
    { 
     this.Load(code); 
    } 

    public string Code { get; set; } 

    public UserGroup Group { get; set; } 
} 

...和UserGroup类。

public class UserGroup : ILoadable 
{ 
    public UserGroup(string code) 
    { 
     this.Load(code); 
    } 

    public string Code { get; set; } 

    public int GroupId { get; set; } 

    // More properties 
} 

然后,我有填充从JSON文件,该文件是由构造方法调用,数据对象的方法:

public static void Load(this ILoadable obj, string code) 
{ 
    string json = GetJsonFromCode(obj.GetType(), code); 
    JsonConvert.PopulateObject(json, obj); 
} 

我想是不保存用户提供其完整的用户组属性数据,但只能使用它的代码,所以它可以通过将代码传递给UserGroup构造函数并从那里获取整个对象来重构。例如像这样:

{ 
    "UserCode": "Admin", 
    "Group": "Administrator" 
} 

我已经尝试过创建一个JsonConverter并设置它用下面的代码本集团物业...

[JsonProperty(ItemConverterType = typeof(StringObjectConverter)] 
public UserGroup Group { get; set; } 

...和转换器:

class StringObjectConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(ILoadable).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     return Activator.CreateInstance(objectType, new object[] { (string)reader.Value }); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     writer.WriteValue(((ILoadable)value).Code); 
    } 
} 

但它似乎并没有工作,因为每次我尝试加载上面看到的JSON,抛出以下异常:

Newtonsoft.Json.JsonSerializationException: 'Error converting value "Administrator" to type 'MyProject.UserGroup'. Path 'Group', line 2, position 10.' 

Inner Exception 
ArgumentException: Could not cast or convert from System.String to MyProject.UserGroup. 

我可以在这里使用一些帮助,因为我不知道如何让这个工作,即使转换器没有改变任何东西。

+0

此外,'PopulateObject'的调用似乎没有运行到我的UserGroup代码/字符串的ReadJson方法中。 –

不是[JsonProperty(ItemConverterType = typeof(StringObjectConverter))]必须使用[JsonConverter(typeof(StringObjectConverter))]

public class User : ILoadable 
{ 
    public User(string code) 
    { 
     this.Load(code); 
    } 

    public string Code { get; set; } 

    [JsonConverter(typeof(StringObjectConverter))] 
    public UserGroup Group { get; set; } 
} 

注:

  • JsonConverter指示JsonSerializer使用指定JsonConverter序列化成员或类时。

    您想指定一个转换器用于UserGroup Group成员,因此这是要应用的属性。

  • JsonPropertyAttribute.ItemConverterType指定一个JsonConverter序列化属性的收集项目时使用。

    如果您有一个集合,例如List<UserGroup> Groups,并且需要为每个项目指定一个转换器,则您希望应用此属性。由于您没有集合,因此这不是使用的正确属性。 (显然,当一个ItemConverterType被应用到一个成员的值被序列化为一个JSON对象时,Json.NET将该转换器应用到该对象的每个成员上,这有点令人吃惊;我找不到任何地方这个明确记录。这说明你看到的例外情况。)

工作.Net fiddle