【问题标题】:How to serialize a type derived from List as an array-like object with JSON.NET如何使用 JSON.NET 将从 List 派生的类型序列化为类似数组的对象
【发布时间】:2015-08-11 20:56:58
【问题描述】:

考虑以下派生自List 的类:

public class Foo : List<string>
{
    public string Bar { get; set; }
}

使用 JSON.NET 对其进行序列化会转储 Bar 属性并生成一个常规数组:

var foo = new Foo() { "a", "b", "c" };
foo.Bar = "baz";
JsonConvert.SerializeObject(foo); // ["a","b","c"]

我可以做些什么来获得以下类似数组的对象作为我的序列化结果?

{"0": "a", "1": "b", "2": "c", "length": 3, "bar": "baz"}

自定义序列化程序是唯一的方法,还是有 JSON.NET 设置可以为我做到这一点?

【问题讨论】:

  • 对于这样一个非常专业的案例,您期望什么样的设置?
  • 我希望派生集合不是那种专门化的并且可以由框架处理。
  • Vache,但是你期望的json是很专业的.....
  • @Vache:您可以尝试封装而不是继承。只要您对在 json 中反映的内容感到满意。
  • @Eser,它是一个简单的类数组对象,是 JavaScript 中常见的概念

标签: c# serialization json.net


【解决方案1】:

我认为获得所需内容的最简单的方法是执行以下操作:

var foo = new Foo() { "a", "b", "c" };
foo.Bar = "baz";

var data = foo
    .Select((value, index) => new { value, index })
    .ToDictionary(wrapper => wrapper.index.ToString(), wrapper => (object)wrapper.value);

data.Add("length", foo.Count);
data.Add("bar", foo.Bar);

var json = JsonConvert.SerializeObject(data);
//{"0":"a","1":"b","2":"c","length":3,"bar":"baz"}

为具有任意数量属性的所有元素解决此问题的更通用的方法将是此代码:

var foo = new Foo() { "a", "b", "c" };
foo.Bar = "baz";
foo.Beer = "beer";

var json = GetJsonWithItemsAndProperties(foo);
//{"0":"a","1":"b","2":"c","length":3,"Bar":"baz","Beer":"beer"}

//...//

private static string GetJsonWithItemsAndProperties<T>(IReadOnlyCollection<T> listWithProperties)
{
    var data = listWithProperties
        .Select((value, index) => new {value, index})
        .ToDictionary(wrapper => wrapper.index.ToString(), wrapper => (object) wrapper.value);

    data.Add("length", data.Count);

    listWithProperties.GetType()
        .GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance |
                        System.Reflection.BindingFlags.DeclaredOnly).ToList()
        .ForEach(p => data.Add(p.Name, p.GetValue(listWithProperties)));

    return JsonConvert.SerializeObject(data);
}

【讨论】:

  • "bar": "baz""length": 3 部分呢?
  • 产生{"0": "a", "1": "b", "2": "c"} 这与我正在寻找的完全不同。缺少长度(类数组对象需要)和派生属性。
  • 我已经更新了我的代码以包括"bar": "baz""length": "3"
  • @DavidLeitner 你认为这是一个好的解决方案吗?好的,它适用于这些 foo 和 bar,但是如果类具有不同的属性并且会有很多类似的类呢?
  • @Vache 正如你所说,Is a custom serializer the only way to go。是的(我的意思是自定义的 JsonConverter。只需 google 即可)。
猜你喜欢
  • 1970-01-01
  • 2018-04-03
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多