序列化实现IEnumerable的类的自定义属性



当前,JSON。NET忽略实现IEnumerable的类上的所有其他属性,并序列化数组。

我如何告诉JSON。NET来序列化自定义属性?我正在尝试序列化下面的PagedList<T>实现:

public interface IPagedList : IEnumerable
{
    int PageIndex { get; }
    int PageSize { get; }
    int TotalCount { get; }
    int TotalPages { get; }
    bool HasPreviousPage { get; }
    bool HasNextPage { get; }
}
public interface IPagedList<T> : IPagedList, IList<T>
{
}
/// <summary>
/// A tried and tested PagedList implementation
/// </summary>
public class PagedList<T> : List<T>, IPagedList<T>
{
    public PagedList(IEnumerable<T> source, int pageIndex, int pageSize) :
        this(source.GetPage(pageIndex, pageSize), pageIndex, pageSize, source.Count()) { }
    public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
    {
        Ensure.Argument.NotNull(source, "source");
        this.TotalCount = totalCount;
        this.TotalPages = totalCount / pageSize;
        if (totalCount % pageSize > 0)
            TotalPages++;
        this.PageSize = pageSize;
        this.PageIndex = pageIndex;
        this.AddRange(source.ToList());
    }
    public int PageIndex { get; private set; }
    public int PageSize { get; private set; }
    public int TotalCount { get; private set; }
    public int TotalPages { get; private set; }
    public bool HasPreviousPage { get { return (PageIndex > 0); } }
    public bool HasNextPage { get { return (PageIndex + 1 < TotalPages); } }
}

我也遇到了同样的问题,最终不得不使用自定义转换器来完成。我的转换器需要一个类型名称列表来操作,而不是全局工作。我学习了你的课程,并编写了一个小型控制台应用程序,它将通过转换器运行你的课程。神奇之处在于设置JsonSerializerSettings以使用EnumerableConverter类。设置完成后,必须在SerializeObject调用中使用settings对象。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var pagedList = new PagedList<MyObject>(
                                new MyObject[] { 
                                    new MyObject { Foo = "Bar" }, 
                                    new MyObject { Foo = "Baz" } 
                                }, 0, 2, 2);
            Debug.WriteLine(JsonConvert.SerializeObject(pagedList));
            // Outputs: [{"Foo":"Bar"},{"Foo":"Baz"}]
            var settings = new JsonSerializerSettings
            {
                Converters = new List<JsonConverter>(
                                new[]{
                                    new EnumerableConverter(
                                       new []{"ConsoleApplication2.PagedList"}, 
                                              false)
                                })
            };
            Debug.WriteLine(JsonConvert.SerializeObject(pagedList, settings));
            // Outputs: 
            //{
            //   "PageIndex":0,
            //   "PageSize":2,
            //   "TotalCount":2,
            //   "TotalPages":1,
            //   "HasPreviousPage":false,
            //   "HasNextPage":false,
            //   "Capacity":4,
            //   "Count":2,
            //   "Items":[
            //      {
            //         "Foo":"Bar"
            //      },
            //      {
            //         "Foo":"Baz"
            //      }
            //   ]
            //}      
        }
    }
    public class MyObject
    {
        public string Foo { get; set; }
    }
    public interface IPagedList : IEnumerable
    {
        int PageIndex { get; }
        int PageSize { get; }
        int TotalCount { get; }
        int TotalPages { get; }
        bool HasPreviousPage { get; }
        bool HasNextPage { get; }
    }
    public interface IPagedList<T> : IPagedList, IList<T>
    {
    }
    /// <summary>
    /// A tried and tested PagedList implementation
    /// </summary>
    public class PagedList<T> : List<T>, IPagedList<T>
    {
        //public PagedList(IEnumerable<T> source, int pageIndex, int pageSize) :
        //    this(source.GetPage(pageIndex, pageSize), pageIndex, pageSize, source.Count()) { }
        public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
        {
            //Ensure.Argument.NotNull(source, "source");
            this.TotalCount = totalCount;
            this.TotalPages = totalCount / pageSize;
            if (totalCount % pageSize > 0)
                TotalPages++;
            this.PageSize = pageSize;
            this.PageIndex = pageIndex;
            this.AddRange(source.ToList());
        }
        public int PageIndex { get; private set; }
        public int PageSize { get; private set; }
        public int TotalCount { get; private set; }
        public int TotalPages { get; private set; }
        public bool HasPreviousPage { get { return (PageIndex > 0); } }
        public bool HasNextPage { get { return (PageIndex + 1 < TotalPages); } }
    }
    public class EnumerableConverter : Newtonsoft.Json.JsonConverter
    {
        private IEnumerable<string> Types { get; set; }
        private bool IsCamelCase { get; set; }
        public EnumerableConverter(IEnumerable<string> types)
            : this(types, true)
        {
        }
        public EnumerableConverter(IEnumerable<string> types, bool isCamelCase)
        {
            if (types == null) throw new ArgumentNullException("types");
            Types = types;
            IsCamelCase = isCamelCase;
        }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteStartObject();
            var foundInnerEnumerable = false;
            foreach (var property in value.GetType().GetProperties()) {
                try {
                    var propVal = property.GetValue(value, null);
                    foundInnerEnumerable |= propVal is IEnumerable;
                    writer.WritePropertyName(NameFor(property.Name));
                    serializer.Serialize(writer, propVal);
                }
                catch (System.Reflection.TargetParameterCountException) { 
                    // Ignore properties such as Item on List<T>
                }
            }
            if (!foundInnerEnumerable) {
                writer.WritePropertyName(NameFor("Items"));
                writer.WriteStartArray();
                foreach (var item in (IEnumerable)value) {
                    serializer.Serialize(writer, item);
                }
                writer.WriteEndArray();
            }
            writer.WriteEndObject();
        }
        private string NameFor(string value)
        {
            if (!IsCamelCase) return value;
            return value[0].ToString().ToLowerInvariant() + value.Substring(1);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
        public override bool CanConvert(Type objectType)
        {
            return Types.Any(t => objectType.FullName.StartsWith(t));
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新