C# 如何序列化json以显示属性值而不是属性名称?

C# 如何序列化json以显示属性值而不是属性名称?,c#,serialization,jsonconvert,C#,Serialization,Jsonconvert,我试图找到一种方法,将对象序列化为以下格式的json字符串,以便满足项目要求 { "id": 123456, "los": { "2019-05-13": [ { "currency": "EUR", "guests": 2, "price": [ 100, 200 ] }, { "currency": "EUR",

我试图找到一种方法,将对象序列化为以下格式的json字符串,以便满足项目要求

{
  "id": 123456,
  "los": {
    "2019-05-13": [
      {
        "currency": "EUR",
        "guests": 2,
        "price": [
          100,
          200
        ]
      },
      {
        "currency": "EUR",
        "guests": 3,
        "price": [
          150,
          250
        ]
      }
    ],
    "2019-05-14": {
      "currency": "EUR",
      "guests": 2,
      "price": [
        300
      ]
    }
  },
}
我创建了以下模型类:

public class Rootobject
{
    public Los los { get; set; }
    public int Id { get; set; }
}

public class Los
{
    public Item[] items{ get; set; }
}

public class Item
{
    public DateTime date {get;set;}
    public string currency { get; set; }
    public int guests { get; set; }
    public int[] price { get; set; }
}

在序列化过程中,可能会以某种方式更改元素的名称,因此将项序列化为“2019-05-13”、“2019-05-14”等?

为此,您需要以下类结构:

public class Rootobject
{
    public int Id { get; set; }
    [JsonConverter(typeof(CustomItemConverter))]
    public Dictionary<DateTime, Item[]> Los { get; set; }
}

public class Item
{
    [JsonIgnore]
    public DateTime Date { get; set; }
    public string Currency { get; set; }
    public int Guests { get; set; }
    public int[] Price { get; set; }
}
公共类根对象
{
公共int Id{get;set;}
[JsonConverter(类型(CustomItemConverter))]
公共字典Los{get;set;}
}
公共类项目
{
[JsonIgnore]
公共日期时间日期{get;set;}
公共字符串货币{get;set;}
公共int来宾{get;set;}
公共int[]价格{get;set;}
}
和自定义转换器:

public class CustomItemConverter : JsonConverter
{
    public override bool CanRead => false;

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Dictionary<DateTime, Item[]>);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var dictionary = (Dictionary<DateTime, Item[]>)value;

        writer.WriteStartArray();
        foreach (var item in dictionary)
        {
            writer.WriteStartObject();
            writer.WritePropertyName(item.Key.Date.ToString("yyyy-MM-dd"));
            serializer.Serialize(writer, item.Value);
            writer.WriteEndObject();
        }
        writer.WriteEndArray();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }
}
公共类CustomItemConverter:JsonConverter
{
public override bool CanRead=>false;
公共覆盖布尔CanConvert(类型objectType)
{
返回objectType==typeof(字典);
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
var dictionary=(dictionary)值;
writer.writestarray();
foreach(字典中的变量项)
{
writer.WriteStartObject();
writer.WritePropertyName(item.Key.Date.ToString(“yyyy-MM-dd”);
serializer.Serialize(writer,item.Value);
writer.WriteEndObject();
}
writer.WriteEndArray();
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
抛出new NotImplementedException(“不必要,因为CanRead为false。该类型将跳过转换器。”);
}
}

与序列化的方式相同:将项目存储在字典中,其中日期字符串是键。如果您不想这样做,您可以编写一个自定义格式设置程序来实现这一点,这样就可以避免使用适当的数据结构。有意义的是,让我告诉您:如果属性名称是一个值,那么它就是一个字典。为了加强键的唯一性,字典被序列化为一个对象,其中键是属性名,值是属性值。还提供一个您希望看到的示例输出,您可以使用
Json.Linq
,就像在这个线程中,为什么我需要CustomItemConverter?CustomConverter允许重写序列化以添加keys属性。是的,这很好,但是自定义转换器增加了可维护性问题。如果他们想像这样序列化多个类的多个属性呢?您必须引入泛型,如果您想要反序列化相同的JSON,您将有更多的工作要做。