JSON. net: Как преобразовать / разбить 1 объект в 2 отдельных массива без родительского узла с JsonConverter ?
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 : одно из возможных решений, предложенное Павел Аниховский , частично ручная работа без 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);