我创建了一个类PagedResult<T> : List<T>
,其中添加了一些成员以便与我们的组件配合使用。但是,当我运行JSON反序列化时,它只对列表进行序列化。如果我使用[JsonObject]
和[JsonProperty]
标记派生类,那么它只会序列化派生类的成员而不是列表。如何同时得到两者?
我创建了一个类PagedResult<T> : List<T>
,其中添加了一些成员以便与我们的组件配合使用。但是,当我运行JSON反序列化时,它只对列表进行序列化。如果我使用[JsonObject]
和[JsonProperty]
标记派生类,那么它只会序列化派生类的成员而不是列表。如何同时得到两者?
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"
]
}
[JsonProperty]
public IEnumerable<T> Elements {
get
{
return this;
}
}
JsonConverter
或使用 JSON 属性(JsonObjectAttribute),那么您可以使用扩展方法: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; }
}
public static class Extensions
{
public static string ToPagedJson<T>(this PagedResult<T> pagedResult)
{
return JsonConvert.SerializeObject(new
{
PageSize = pagedResult.PageSize,
PageIndex = pagedResult.PageIndex,
TotalItems = pagedResult.TotalItems,
TotalPages = pagedResult.TotalPages
Items = pagedResult
});
}
}
IEnumerable
接口的类视为数组。您可以通过在类上添加[JsonObject]
属性来覆盖此行为,但这样只有对象属性会被序列化。我的经验略有不同:OP是从List<T>
派生的,而我已经在基类中实现了IList<T>
,并且直接在序列化对象中实现了它以获取我的IEnumerable
实现。在两种情况下,只要使用[JsonObject]
进行装饰,我就可以获得添加的属性和集合对象。可能是由于Json.NET的新版本(12.0.0)。 - Bob Sammers