using System.Collections.Generic;
using Newtonsoft.Json.Linq;
public static void Main()
var users = new List<UserDTO>
new UserDTO { Id = 1, Name = "Joe Schmoe" },
new UserDTO { Id = 2, Name = "John Doe" },
new UserDTO { Id = 3, Name = "Bob Smith" }
PagedData<UserDTO> data1 = new PagedData<UserDTO>("Users", users, 3, 1, 0, 10);
string json = JsonConvert.SerializeObject(data1, Formatting.Indented);
Console.WriteLine(new string('-', 40));
var items = new List<ItemDTO>
new ItemDTO { Id = 1, Name = "Hammer" },
new ItemDTO { Id = 2, Name = "Saw" },
new ItemDTO { Id = 3, Name = "Drill" },
new ItemDTO { Id = 4, Name = "Wrench" },
PagedData<ItemDTO> data2 = new PagedData<ItemDTO>("Items", items, 4, 1, 0, 10);
json = JsonConvert.SerializeObject(data2, Formatting.Indented);
public class PagedDataConverter : JsonConverter
public override bool CanConvert(Type objectType)
return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(PagedData<>);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
Type type = value.GetType();
var bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
string dataPropertyName = (string)type.GetProperty("DataPropertyName", bindingFlags).GetValue(value);
if (string.IsNullOrEmpty(dataPropertyName))
dataPropertyName = "Data";
JObject jo = new JObject();
jo.Add(dataPropertyName, JArray.FromObject(type.GetProperty("Data").GetValue(value)));
foreach (PropertyInfo prop in type.GetProperties().Where(p => !p.Name.StartsWith("Data")))
jo.Add(prop.Name, new JValue(prop.GetValue(value)));
public override bool CanRead
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
throw new NotImplementedException();
[JsonConverter(typeof(PagedDataConverter))]
public class PagedData<T>
public PagedData(string dataPropertyName, IEnumerable<T> data, int count, int currentPage, int offset, int rowsPerPage, int? previousPage = null, int? nextPage = null)
DataPropertyName = dataPropertyName;
CurrentPage = currentPage;
RowsPerPage = rowsPerPage;
PreviousPage = previousPage;
private string DataPropertyName { get; set; }
public IEnumerable<T> Data { get; private set; }
public int Count { get; private set; }
public int CurrentPage { get; private set; }
public int Offset { get; private set; }
public int RowsPerPage { get; private set; }
public int? PreviousPage { get; private set; }
public int? NextPage { get; private set; }
public int Id { get; set; }
public string Name { get; set; }
public int Id { get; set; }
public string Name { get; set; }