C# 使用具有相同名称的多个节点生成JSON
我需要在c中创建转换为以下JSON的对象:C# 使用具有相同名称的多个节点生成JSON,c#,.net,json,json.net,C#,.net,Json,Json.net,我需要在c中创建转换为以下JSON的对象: { "Order": { "CustomerCode": "9999999", "Note": "New Order for Test -- UNIT TEST", "Stops": { "Stop": { "Sequence": "1", "StopType": "P", "N
{
"Order": {
"CustomerCode": "9999999",
"Note": "New Order for Test -- UNIT TEST",
"Stops": {
"Stop": {
"Sequence": "1",
"StopType": "P",
"Name": "CVS"
},
"Stop": {
"OrderStopID": "5",
"Sequence": "2",
"StopType": "D",
}
},
"Jobs": {
"Job": {
"Sequence": "1",
"Drivers": {
"Driver": {
"Sequence": "1",
"DriverCode": "09"
},
"Driver": {
"Sequence": "2"
}
}
}
}
}
}
以下是我创建的用于表示此内容的对象:
public class RootObject
{
public Order Order { get; set; }
}
public class Order
{
public string CustomerCode { get; set; }
public List<Stop> Stops { get; set; }
public List<Job> Jobs { get; set; }
}
您可以使用JsonConverter执行以下操作:
public class ArrayConverter : JsonConverter
{
private readonly string _propertyName;
public ArrayConverter(string propertyName)
{
this._propertyName = propertyName;
}
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(List<>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
IList items = (IList)Activator.CreateInstance(objectType);
var modelType = objectType.IsArray ? objectType.GetElementType() : objectType.GetGenericArguments().Single();
if (reader.TokenType != JsonToken.StartObject)
{
throw new ArgumentOutOfRangeException(nameof(reader), "Expected object.");
}
while (reader.Read() && reader.TokenType != JsonToken.EndObject)
{
reader.Read();
items.Add(serializer.Deserialize(reader, modelType));
}
return items;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is IEnumerable enumerableValue)
{
JObject obj = new JObject();
writer.WriteStartObject();
foreach (var val in enumerableValue)
{
writer.WritePropertyName(_propertyName);
serializer.Serialize(writer, val);
}
writer.WriteEndObject();
}
else
{
throw new ArgumentOutOfRangeException(nameof(value), "Value does not implement IEnumerable.");
}
}
}
您可以使用JsonConverter执行以下操作:
public class ArrayConverter : JsonConverter
{
private readonly string _propertyName;
public ArrayConverter(string propertyName)
{
this._propertyName = propertyName;
}
public override bool CanConvert(Type objectType)
{
return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(List<>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
IList items = (IList)Activator.CreateInstance(objectType);
var modelType = objectType.IsArray ? objectType.GetElementType() : objectType.GetGenericArguments().Single();
if (reader.TokenType != JsonToken.StartObject)
{
throw new ArgumentOutOfRangeException(nameof(reader), "Expected object.");
}
while (reader.Read() && reader.TokenType != JsonToken.EndObject)
{
reader.Read();
items.Add(serializer.Deserialize(reader, modelType));
}
return items;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is IEnumerable enumerableValue)
{
JObject obj = new JObject();
writer.WriteStartObject();
foreach (var val in enumerableValue)
{
writer.WritePropertyName(_propertyName);
serializer.Serialize(writer, val);
}
writer.WriteEndObject();
}
else
{
throw new ArgumentOutOfRangeException(nameof(value), "Value does not implement IEnumerable.");
}
}
}
您正在尝试生成的JSON在本机的任何标准下都不会进行验证。你为什么要这样生成JSON?@John有一个POST API只接受这种格式作为请求数据。你可能需要一个自定义转换器来获得所需的格式。StopType之后还有一个任性的逗号:D,OP,根据你现在删除的另一个问题,我已经在这个问题的原始答案中添加了JsonConverter的read部分。我希望这有帮助-您正在尝试生成的JSON在本机的任何标准下都不会进行验证。你为什么要这样生成JSON?@John有一个POST API只接受这种格式作为请求数据。你可能需要一个自定义转换器来获得所需的格式。StopType之后还有一个任性的逗号:D,OP,根据你现在删除的另一个问题,我已经在这个问题的原始答案中添加了JsonConverter的read部分。我希望这有帮助-看起来好像第三级对象只得到最后一个,例如我把两个停止对象放入一个数组,但我只得到最后一个驱动对象,它有一个更深的缩进层,似乎不明白为什么在第三级,它只需要最后一个对象,而不是将两个驱动程序添加到数组中。使用第三个缩进驱动程序的想法只是编写最后一个?@Eric我不知道。我甚至发现它似乎从未为转换器的读取部分提供多个。不过,我现在太困了,再也看不下去了:-我明天会尽量找时间的。我可能需要下载JSON.NET的代码并进行调试以获得一个想法。@Eric Well。。。嗯,看起来JSON.NET删除了重复项。请看@Eric,我已将其修改为可用。我将其限制为只与列表一起使用,而不与其他列表一起使用,所以如果您需要不同的内容,可能需要对其进行调整。鉴于JSON.NET的部分代码可以阻止重复的属性名称,我不能保证这段代码能够经受住对JSON.NET的更新,因此如果您还没有进行单元测试,我建议对代码进行单元测试,以便知道对JSON.NET的更改是否会破坏代码。看起来好像第三级对象只得到最后一个,例如,我将两个停止对象放入一个数组中,但我只得到最后一个驱动器对象,它有一个更深的缩进级别,似乎不明白为什么在第三级,它只需要最后一个对象,而不是将两个驱动程序添加到数组中。使用第三个缩进驱动程序的想法只是编写最后一个?@Eric我不知道。我甚至发现它似乎从未为转换器的读取部分提供多个。不过,我现在太困了,再也看不下去了:-我明天会尽量找时间的。我可能需要下载JSON.NET的代码并进行调试以获得一个想法。@Eric Well。。。嗯,看起来JSON.NET删除了重复项。请看@Eric,我已将其修改为可用。我将其限制为只与列表一起使用,而不与其他列表一起使用,所以如果您需要不同的内容,可能需要对其进行调整。鉴于JSON.NET的某些部分有代码来阻止重复的属性名称,我不能保证这段代码能够经受住对JSON.NET的更新,因此,如果您还没有进行单元测试,我建议您对代码进行单元测试,以便您知道对JSON.NET的更改是否会破坏它。