【问题标题】:How to serialize json in order to display property value instead of property name?如何序列化 json 以显示属性值而不是属性名称?
【发布时间】:2020-04-28 03:17:12
【问题描述】:

我正在尝试找到一种将对象序列化为以下格式的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; }
}

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

【问题讨论】:

  • 与序列化它的方式相同:将项目存储在字典中,其中日期字符串是键。如果您不想要这个,您可以编写一个自定义格式化程序来执行此操作,因此在不使用适当的数据结构方面确实有很长的路要走。
  • 有道理,我试试
  • 专业提示:如果属性名称是一个值,那么它就是一个字典。为了强制键唯一性,字典被序列化为一个对象,其中键是属性名称,值是属性值。
  • 还提供您希望看到的示例输出
  • 你可以使用Json.Linq,就像在这个线程中Getting the name / key of a JToken with JSON.net

标签: c# serialization jsonconvert


【解决方案1】:

为此,您需要这个类结构:

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; }
}

和自定义转换器:

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?
  • 自定义转换器允许覆盖序列化以添加键属性。 doc
  • 是的,这很好,但是自定义转换器增加了可维护性问题。如果他们想像这样序列化多个类的多个属性怎么办?你必须引入泛型,如果你想反序列化相同的 JSON,你还有更多的工作要做。
猜你喜欢
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多