一尘不染

如何获取json.net来序列化从List派生的类的成员?

c#

我创建了一个PagedResult<T> : List<T>包含几个添加的成员的类,以便使用我们的组件之一。但是,当我运行json解串器时,它只会序列化列表。如果我的标记与派生类[JsonObject][JsonProperty]然后它只会序列化派生类的成员,而不是名单。如何获得两者?


阅读 211

收藏
2020-05-19

共1个答案

一尘不染

默认情况下,Json.Net将把任何实现IEnumerable为数组的类视为。您可以通过用[JsonObject]属性装饰类来覆盖此行为,但是如您所见,只有对象属性会被序列化。该列表本身不会被序列化,因为它不是通过公共属性公开的(而是通过GetEnumerator()方法公开的)。

如果两者都想要,则可以按照@Konrad的建议进行操作,并在派​​生类上提供一个公共属性以显示列表,或者可以编写自定义JsonConverter序列化整个对象。后一种方法的示例如下。

假设您的PagedResult<T>课程如下所示:

class PagedResult<T> : List<T>
{
    public int PageSize { get; set; }
    public int PageIndex { get; set; }
    public int TotalItems { get; set; }
    public int TotalPages { get; set; }
}

您可以像这样制作一个转换器:

class PagedResultConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(PagedResult<T>));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        PagedResult<T> result = (PagedResult<T>)value;
        JObject jo = new JObject();
        jo.Add("PageSize", result.PageSize);
        jo.Add("PageIndex", result.PageIndex);
        jo.Add("TotalItems", result.TotalItems);
        jo.Add("TotalPages", result.TotalPages);
        jo.Add("Items", JArray.FromObject(result.ToArray(), serializer));
        jo.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        PagedResult<T> result = new PagedResult<T>();
        result.PageSize = (int)jo["PageSize"];
        result.PageIndex = (int)jo["PageIndex"];
        result.TotalItems = (int)jo["TotalItems"];
        result.TotalPages = (int)jo["TotalPages"];
        result.AddRange(jo["Items"].ToObject<T[]>(serializer));
        return result;
    }
}

(还请注意,此方法不需要[JsonObject][JsonProperty]属性,因为要序列化的内容已封装在转换器类中。)

这是演示如何运行转换器的演示:

class Program
{
    static void Main(string[] args)
    {
        PagedResult<string> result = new PagedResult<string> { "foo", "bar", "baz" };
        result.PageIndex = 0;
        result.PageSize = 10;
        result.TotalItems = 3;
        result.TotalPages = 1;

        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.Converters.Add(new PagedResultConverter<string>());
        settings.Formatting = Formatting.Indented;

        string json = JsonConvert.SerializeObject(result, settings);
        Console.WriteLine(json);
    }
}

输出:

{
  "PageSize": 10,
  "PageIndex": 0,
  "TotalItems": 3,
  "TotalPages": 1,
  "Items": [
    "foo",
    "bar",
    "baz"
  ]
}
2020-05-19