How can I serialize/deserialize a kind of json mixing object and list of object at the same level in c#?

huangapple go评论76阅读模式
英文:

How can I serialize/deserialize a kind of json mixing object and list of object at the same level in c#?

问题

我正在使用Newtonsoft JSON,并且需要序列化/反序列化这种类型的JSON:

[
  {
    "value": "value1",
    "field": "field1"
  },
  {
    "value": "value2",
    "field": "field2"
  },
  {
    "value": "value3",
    "field": "field3"
  },
  [
    {
      "value": "value4",
      "field": "field4"
    },
    {
      "value": "value4",
      "field": "field5"
    }
  ]
]

正如您所见,我可以在同一级别同时拥有一个对象或这个对象的列表。我已经为该对象创建了一个类,但我不知道如何使序列化过程处理这种类型的JSON,或者是否可以这样做。

编辑:我没有选择处理我收到的JSON。因此,请不要认为我喜欢这样做,如果您这么认为,是错误的。

英文:

I'm using newtonsoft json, and I need to serialize/deserialize this kind of json:

[
  {
    "value": "value1",
    "field": "field1"
  },
  {
    "value": "value2",
    "field": "field2"
  },
  {
    "value": "value3",
    "field": "field3"
  },
  [
    {
      "value": "value4",
      "field": "field4"
    },
    {
      "value": "value4",
      "field": "field5"
    }
  ]
]

As you can see, I can have an object or a list of this object at the same level. I've created a class for the object but I don't know how to make the serialization process this kind of json, or if it's possible to do.

EDIT: I don't have the choice to process that json as it comes to me. So please, if you think I like this, you're wrong.

答案1

得分: 1

你可以创建一个自定义的JSON转换器:

Result result = JsonConvert.DeserializeObject<Result>(json, new ArrayJsonConverter());

以下是自定义的ArrayJsonConverter类:

public class ArrayJsonConverter : JsonConverter<Result>
{
    public override Result ReadJson(JsonReader reader, Type objectType, Result existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        JArray jArr = JArray.Load(reader);

        var result = new Result { Items = new List<Item>(), ListItems = new List<List<Item>>() };

        foreach (var item in jArr)
            if (item.Type == JTokenType.Array) result.ListItems.Add(item.ToObject<List<Item>>());
            else result.Items.Add(item.ToObject<Item>());

        return result;
    }

    public override void WriteJson(JsonWriter writer, Result value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

接下来是Result类:

public class Result
{
    public List<Item> Items { get; set; }
    public List<List<Item>> ListItems { get; set; }
}

最后是Item类:

public class Item
{
    public string value { get; set; }
    public string field { get; set; }
}
英文:

you can create a custom json converter

Result result = JsonConvert.DeserializeObject&lt;Result&gt;(json, new ArrayJsonConverter())

public class ArrayJsonConverter : JsonConverter&lt;Result&gt;
{
	public override Result ReadJson(JsonReader reader, Type objectType, Result existingValue, bool hasExistingValue, JsonSerializer serializer)
	{
		JArray jArr = JArray.Load(reader);

		var result = new Result { Items = new List&lt;Item&gt;(), ListItems = new List&lt;List&lt;Item&gt;&gt;() };

		foreach (var item in jArr)
			if (item.Type == JTokenType.Array) result.ListItems.Add(item.ToObject&lt;List&lt;Item&gt;&gt;());
			else result.Items.Add(item.ToObject&lt;Item&gt;());

		return result;
	}

	public override void WriteJson(JsonWriter writer, Result value, JsonSerializer serializer)
	{
		throw new NotImplementedException();
	}
}

public class Result
{
	public List&lt;Item&gt; Items { get; set; }
	public List&lt;List&lt;Item&gt;&gt; ListItems { get; set; }
}

public class Item
{
	public string value { get; set; }
	public string field { get; set; }
}

答案2

得分: 0

以下是我找到的解决方案,感谢您的帮助:

public class Item
{
    public string Value { get; set; }
    public string Field { get; set; }
}

public class ItemContainer
{
    public List<Item> Items { get; set; }
    public List<List<Item>> NestedItems { get; set; }
}

public class ItemContainerConverter : JsonConverter<ItemContainer>
{
    public override ItemContainer ReadJson(JsonReader reader, Type objectType, ItemContainer existingValue,
        bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonObject = JArray.Load(reader);
        var itemContainer = new ItemContainer
        {
            Items = new List<Item>(),
            NestedItems = new List<List<Item>>()
        };

        foreach (var token in jsonObject)
        {
            if (token.Type == JTokenType.Array)
            {
                var nestedItemList = token.ToObject<List<Item>>();
                itemContainer.NestedItems.Add(nestedItemList);
            }
            else if (token.Type == JTokenType.Object)
            {
                var item = token.ToObject<Item>();
                itemContainer.Items.Add(item);
            }
        }

        return itemContainer;
    }

    public override void WriteJson(JsonWriter writer, ItemContainer value, JsonSerializer serializer)
    {
        writer.WriteStartArray();

        foreach (var item in value.Items)
        {
            serializer.Serialize(writer, item);
        }

        if (value.NestedItems != null && value.NestedItems.Any())
        {
            writer.WriteStartArray();
            foreach (var nestedItem in value.NestedItems.SelectMany(nestedList => nestedList))
            {
                serializer.Serialize(writer, nestedItem);
            }
            writer.WriteEndArray();
        }

        writer.WriteEndArray();
    }
}

以下是如何使用它的方式:

var settings = new JsonSerializerSettings()
{
    ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new SnakeCaseNamingStrategy()
    }
};
settings.Converters.Add(new ItemContainerConverter());

var rootObject = JsonConvert.DeserializeObject<ItemContainer>(jsonString, settings);
var json = JsonConvert.SerializeObject(rootObject, settings);

希望这对您有所帮助!如果您有任何其他问题,请随时提出。

英文:

Here is the solution I found thanks to your help:

public class Item
{
    public string Value { get; set; }
    public string Field { get; set; }
}

public class ItemContainer
{
    public List&lt;Item&gt; Items { get; set; }
    public List&lt;List&lt;Item&gt;&gt; NestedItems { get; set; }
}

public class ItemContainerConverter : JsonConverter&lt;ItemContainer&gt;
{
    public override ItemContainer ReadJson(JsonReader reader, Type objectType, ItemContainer existingValue,
        bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonObject = JArray.Load(reader);
        var itemContainer = new ItemContainer
        {
            Items = new List&lt;Item&gt;(),
            NestedItems = new List&lt;List&lt;Item&gt;&gt;()
        };

        foreach (var token in jsonObject)
        {
            if (token.Type == JTokenType.Array)
            {
                var nestedItemList = token.ToObject&lt;List&lt;Item&gt;&gt;();
                itemContainer.NestedItems.Add(nestedItemList);
            }
            else if (token.Type == JTokenType.Object)
            {
                var item = token.ToObject&lt;Item&gt;();
                itemContainer.Items.Add(item);
            }
        }

        return itemContainer;
    }

    public override void WriteJson(JsonWriter writer, ItemContainer value, JsonSerializer serializer)
    {
        writer.WriteStartArray();

        foreach (var item in value.Items)
        {
            serializer.Serialize(writer, item);
        }

        if (value.NestedItems != null &amp;&amp; value.NestedItems.Any())
        {
            writer.WriteStartArray();
            foreach (var nestedItem in value.NestedItems.SelectMany(nestedList =&gt; nestedList))
            {
                serializer.Serialize(writer, nestedItem);
            }
            writer.WriteEndArray();
        }

        writer.WriteEndArray();
    }
}

And there is how to use it:

var settings = new JsonSerializerSettings()
{
    ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new SnakeCaseNamingStrategy()
    }
};
settings.Converters.Add(new ItemContainerConverter());

var rootObject = JsonConvert.DeserializeObject&lt;ItemContainer&gt;(jsonString, settings);
var json = JsonConvert.SerializeObject(rootObject, settings);

huangapple
  • 本文由 发表于 2023年7月4日 21:27:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定