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

我需要在c中创建转换为以下JSON的对象:

{
    "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的更改是否会破坏它。