【问题标题】:Make/Load JSON of a custom class as if it is a variable制作/加载自定义类的 JSON,就好像它是一个变量一样
【发布时间】:2021-06-05 20:52:07
【问题描述】:

当我通过 Newtonsoft 序列化创建自定义类的 JSON 字符串时,我希望我的自定义类表现为(字符串)变量。

F.e.

public class YearMonth
{
    public YearMonth(int year, int month) {
    }

    [JsonConstructor]
    public YearMonth(string yearMonth) {
    }
}

public class Data
{
    public YearMonth startYearMonth { get; set; }
}

var data = new Data() { startYearMonth = new YearMonth(2021, 1) };

数据的 JSON 应该是:

{ startYearMonth = "202101" }

我应该如何意识到这一点?

我已经通过 [JsonConstructor] 属性进行了反序列化。

【问题讨论】:

标签: c# json class serialization deserialization


【解决方案1】:

解决此问题的一种方法是实现自定义JsonConverter<T>

public class SimpleRepresentationConverter : JsonConverter<YearMonth>
{
    public override void WriteJson(JsonWriter writer, YearMonth value, JsonSerializer serializer)
        => writer.WriteValue(value.ToString());

    public override YearMonth ReadJson(JsonReader reader, Type objectType, YearMonth existingValue, bool hasExistingValue, JsonSerializer serializer)
        => new YearMonth((string) reader.Value);
}

在这里,我们依赖 ToString 已被覆盖以所需格式打印数据。

我已经扩展了您的 YearMonth 课程:

public class YearMonth
{
    public int Year { get; }
    public int Month { get; }
    public YearMonth(int year, int month)
    {
        Year = year;
        Month = month;
    }

    private YearMonth(string year, string month)
        :this(Convert.ToInt32(year), Convert.ToInt32(month))
    { }

    public YearMonth(string yearMonth)
        :this(yearMonth.Substring(0,4), yearMonth.Substring(4, 2))
    { }

    public override string ToString() => $"{this.Year}{this.Month:D2}";
}
  • 我还添加了一些额外的成员以便能够轻松测试它
  • 请记住,此实现非常脆弱,因为它会在收到格式错误的输入时中断。

另请注意,不需要JsonConstructor 属性。

我们装饰Data类的startYearMonth属性:

public class Data
{
    [JsonConverter(typeof(SimpleRepresentationConverter))]
    public YearMonth startYearMonth { get; set; }
}

用法

Console.WriteLine(JsonConvert.SerializeObject(new Data() { startYearMonth = new YearMonth(2021, 02)}));
Console.WriteLine(JsonConvert.DeserializeObject<Data>("{\"startYearMonth\":\"202102\"}")?.startYearMonth?.Month);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多