C#解析JSON数组会覆盖列表中的值

时间:2018-01-11 08:53:23

标签: c# json serialization arraylist

我遇到了将json文件反序列化到我的类中的问题。 Json文件看起来像这样:

    { 
    "DataFile": {
        "header":{
            "version": "123",
            "date": "01.01.01",         
        },
        "customer": {
            "fID": "12-35-58",
            "nameCust": "CompanyName",
            "adressCust":{
                "zip": "0000",
                "city": "Foovile",
                "streetNr": "1",
                "post": "FoovilePost",
                "street": "DunnoStr",
            },
        },
        "content": [
                {
                    "invoice":{
                        "DFID":"538",
                    },
                    "invoice":{
                        "DFID":"500",
                    },
                    "invoice":{
                        "DFID":"550",
                    },
                    "receipt":{
                        "DFID":"758",
                    },
                    "receipt":{
                        "DFID":"75",
                    },
                }               
            ],

    }
    }

内容数组之前的所有内容都反序列化很好,所以为了保持清晰,我将跳过我班级的部分内容。相关位看起来像这样:

class DFFile
{
    public DF Df { get; set; }
}

class DF
{
    public Header header { get; set; }
    public Customer customer { get; set; }
    public List<DFContent> content { get; set; }
}
class DFContent
{
    public Invoice invoice { get; set; }
    public Receipt receipt { get; set; }
}
class Invoice
{
    public int DFID { get; set; }
}
class Receipt
{
    public int DFID { get; set; }
}

我将这样反序列化为DFFile实例:

DFFile sample = JsonConvert.DeserializeObject<DFFile>(json);

我的问题是它反序列化没有错误但是sample.DF.content只有一个元素具有发票和收据,每个类型的最后一个id。我要查找的结果是列表,其中json内容数组的每个项目都有新元素。 我可以改变我的课程但是这个json构建的方式是一成不变的,不能对它做任何事情并且必须处理它。

有没有办法阻止它改变内容的最后一个元素并添加新内容?

2 个答案:

答案 0 :(得分:0)

您的内容设置为包含数组但您只有一个项目,其中包含三个发票和两个收据值。假设您希望DFContent持有收据或发票,请将其更改为如下所示:

 "content": [
                {"invoice":{
                        "DFID":"538",
                }},
                {"invoice":{
                        "DFID":"500",
                }},
                {"invoice":{
                        "DFID":"550",
                }},
                {"receipt":{
                        "DFID":"758",
                }},
                {"receipt":{
                        "DFID":"75",
                }}               
            ],

答案 1 :(得分:0)

由于您无法更改JSON,我认为您可以更改类结构。

请考虑这些课程:

class DF
{
    // Other properties...
    [JsonConverter(typeof(FunnyListConverter))]
    public List<Content> content { get; set; }
}

class Content
{
    public int DFID { get; set; }
}

class Invoice : Content
{
}
class Receipt : Content
{
}

这是FunnyListConverter:

public class FunnyListConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var content = new List<Content>();
        var currentType = "";
        Invoice currentInvoice = null;
        Receipt currentReceipt = null;
        while (reader.Read())
        {
            if (reader.TokenType == JsonToken.EndArray)
            {
                break;
            }
            if (reader.Value?.ToString() == "invoice")
            {
                currentInvoice = new Invoice();
                currentType = "invoice";
            }
            if (reader.Value?.ToString() == "receipt")
            {
                currentReceipt = new Receipt();
                currentType = "receipt";
            }
            if (reader.Path.Contains("DFID") && reader.Value?.ToString() != "DFID")
            {
                switch (currentType)
                {
                    case "invoice":
                        currentInvoice.DFID = int.Parse(reader.Value.ToString());
                        content.Add(currentInvoice);
                        currentInvoice = null;
                        break;
                    case "receipt":
                        currentReceipt.DFID = int.Parse(reader.Value.ToString());
                        content.Add(currentReceipt);
                        currentReceipt = null;
                        break;
                }
            }
        }
        return content;
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
          }
            if (reader.Value?.ToString() == "receipt")
            {
                currentReceipt = new Receipt();
                currentType = "receipt";
            }
            if (reader.Path.Contains("DFID") && reader.Value?.ToString() != "DFID")
            {
                switch (currentType)
                {
                    case "invoice":
                        currentInvoice.DFID = int.Parse(reader.Value.ToString());
                        content.Add(currentInvoice);
                        currentInvoice = null;
                        break;
                    case "receipt":
                        currentReceipt.DFID = int.Parse(reader.Value.ToString());
                        content.Add(currentReceipt);
                        currentReceipt = null;
                        break;
                }
            }
        }
        return content;
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }
}