如何将自定义列表类转换为json?

时间:2014-02-07 13:10:51

标签: c# json json.net

我有以下课程(简化版本):

public class DemoList<K, V>
{
    private List<SomeItem<K, V>> _listItems;

    public DemoList()
    {
        _listItems = new List<SomeItem<K, V>>();
    }
    public Int32 Count
    {
        get { return _listItems.Count; }
    }
    public void Add(SomeItem<K, V> item)
    {
        _listItems.Add(item);
    }
    public SomeItem<K, V> this[int index] 
    {
        get { return _listItems[index]; }
    }
}

SomeItem代码:

public class SomeItem<K, V>
{
    private K _key;
    private V _value;
    public SomeItem(K key, V value)
    {
        _key = key;
        _value = value;
    }
    public K Key
    {
        get { return _key; }
        set { _key = value; }
    }
    public V Value
    {
        get { return _value; }
        set { _value = value; }
    }
}

当我在演示列表中添加一些值时:

DemoList<String, String> dl = new DemoList<string, string>();
dl.Add(new SomeItem<string, string>("bla1", "diebla1"));
dl.Add(new SomeItem<string, string>("bla2", "diebla2"));
dl.Add(new SomeItem<string, string>("bla3", "diebla3"));
dl.Add(new SomeItem<string, string>("bla4", "diebla4"));

现在我想将它转换为json,使用NewtonSoft.Json ...就像这样:

JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
var jsonContent = JsonConvert.SerializeObject(dl, serializerSettings);

这导致以下JSon:

{"Count":4}

我希望的json是这样的:

{
  "items": [
    { "bla1": "diabla1"},
    {"bla2": "diabla2"},
    {"bla3": "diabla3"},
    {"bla4": "diabla4"}
  ]
}

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

要让Json.Net序列化项目列表,您可以将项目公开为公共属性(正如其他人所建议的那样),或者使用[JsonProperty]属性标记列表,如下所示:

    [JsonProperty("items")]
    private List<SomeItem<K, V>> _listItems;

如果要取消输出中的Count,请使用[JsonIgnore]标记该属性:

    [JsonIgnore]
    public Int32 Count
    {
        get { return _listItems.Count; }
    }

通过上述更改,我们获得了以下JSON,它更接近,但仍然不是您想要的:

{
  "items": [
    { "key": "bla1", "value": "diebla1" },
    { "key": "bla2", "value": "diebla2" },
    { "key": "bla3", "value": "diebla3" },
    { "key": "bla4", "value": "diebla4" }
  ]
}

要将商品转换为您想要的格式,您需要这样的自定义JsonConverter类:

class SomeItemConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && 
            objectType.GetGenericTypeDefinition() == typeof(SomeItem<,>);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken token = JToken.FromObject(value);
        JObject obj = new JObject();
        obj.Add(token["Key"].ToString(), token["Value"]);
        obj.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        JProperty prop = token.Children<JProperty>().First();
        JObject obj = new JObject();
        obj.Add("Key", prop.Name);
        obj.Add("Value", prop.Value);
        return obj.ToObject(objectType);
    }
}

将转换器添加到JsonSerializerSettings并像以前一样序列化列表:

JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
serializerSettings.Converters.Add(new SomeItemConverter());
var jsonContent = JsonConvert.SerializeObject(dl, serializerSettings);
Console.WriteLine(jsonContent);

现在我们有了这个JSON:

{
    "items": [
        { "bla1":"diebla1" },
        { "bla2":"diebla2" },
        { "bla3":"diebla3" },
        { "bla4":"diebla4" }
    ]
}

答案 1 :(得分:1)

在DemoList中创建返回_listItems的任何方法。然后在json序列化程序中调用getter方法将提供所需的json。