【发布时间】:2020-03-03 14:35:05
【问题描述】:
JSON.net:如何使用 JsonConverter 在没有父节点的情况下将 1 个对象 转换/拆分为 2 个单独的数组 em>?
JSON - 实际:
{"Name":"Bus",
"Type":"Vehicle",
"SymCollection":[
{"ids":[0,1]},
{"weights":[100,50]}
]}
JSON - 预期:
{"Name":"Bus",
"Type":"Vehicle",
"ids":[0,1],
"weights":[100,50]
}
C# – 源对象(无法更改):
class TestClass
{
public string Name;
public string Type;
public SymCollection SymCollection;
}
[JsonConverter(typeof(SymCollectionConverter))]
class SymCollection
{
public int[] Ids;
public int[] Weights;
}
C# – JsonConverter。我该如何改变它?
class SymCollectionConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
SymCollection inputContainer = (SymCollection)value;
// Need to delete next line – do not need any parent node.
writer.WriteStartArray();
writer.WriteStartObject();
writer.WritePropertyName("ids");
writer.WriteStartArray();
foreach (var id in inputContainer.Ids)
{
writer.WriteValue(id);
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.WriteStartObject();
writer.WritePropertyName("weights");
writer.WriteStartArray();
foreach (var weight in inputContainer.Weights)
{
writer.WriteValue(weight);
}
writer.WriteEndArray();
writer.WriteEndObject();
// So, and delete next line too.
writer.WriteEndArray();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return typeof(SymCollection) == objectType;
}
}
很遗憾,TestClass 和 SymCollection 的结构无法更改。
更新 1:Pavel Anikhouski 提出的一种可能的解决方案,部分手工制作,没有 JsonConverter:
class TestClass
{
public string Name;
public string Type;
[JsonIgnore]// Ignore and process it manually.
public SymCollection SymCollection;
public string ToJson()
{
// --> MAIN ATTENTION HERE <
// Create JSON without SymCollection.
var resultJObject = JObject.FromObject(this);
// Add missing IDs and weights.
var symbolIdsAndWeights = SymCollection.GetIdsAndWeightsJTokens();
resultJObject.Add(symbolIdsAndWeights.ids);
resultJObject.Add(symbolIdsAndWeights.weights);
// Convert to string.
string resultJson = resultJObject.ToString(Formatting.None);
return resultJson;
}
}
[JsonConverter(typeof(SymCollectionConverter))]
class SymCollection
{
public int[] Ids;
public int[] Weights;
public (JToken ids, JToken weights) GetIdsAndWeightsJTokens()
{
JTokenWriter idsWriter = new JTokenWriter();
idsWriter.WriteStartObject();
idsWriter.WritePropertyName("ids");
idsWriter.WriteStartArray();
foreach (var id in Ids)
{
idsWriter.WriteValue(id);
}
idsWriter.WriteEndArray();
idsWriter.WriteEndObject();
JTokenWriter weightsWriter = new JTokenWriter();
weightsWriter.WriteStartObject();
weightsWriter.WritePropertyName("weights");
weightsWriter.WriteStartArray();
foreach (var weight in Weights)
{
weightsWriter.WriteValue(weight);
}
weightsWriter.WriteEndArray();
weightsWriter.WriteEndObject();
return (idsWriter.Token.First, weightsWriter.Token.First);
}
}
以及用法为:
TestClass testObject = new TestClass();
string resultJsonStr = testObject.ToJson();
Console.WriteLine(resultJsonStr);
【问题讨论】:
-
您是否认为
JsonConverter只是一个选项?Json.Linq对你有意义吗? -
从预期的
json中删除最后一行的] -
@Sajid 谢谢,已修复!
-
@PavelAnikhouski 请您发布一个如何使用 LINQ 修复它的简单示例? TestClass 背后的真正类是巨大的,所以只修复 SymCollection 会非常好。
-
@OlegZarevennyi 我已经添加了答案,请看一下
标签: c# json serialization json.net