使用非基本属性将对象填充为来自JSON的String

时间:2017-09-14 20:34:07

标签: c# json exception converter populate

我有以下两个示例类。首先是用户类......

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属性数据保存用户,而只保存其代码,因此可以通过将代码传递给UserGroup构造函数并从那里获取整个对象来重建它。例如:

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

我已经尝试使用以下代码创建一个JsonConverter并为Group属性设置它......

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

我可以在这里使用一些帮助,因为我不知道如何让它工作,甚至转换器也不会改变任何东西。

1 个答案:

答案 0 :(得分:0)

而不是[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将转换器应用于该对象的每个成员。这有点令人惊讶;我可以&#39;找到任何明确记录的地方。这说明你看到的例外情况。)

工作.Net fiddle