在 C# 中将类与纯文本值进行序列化

问题描述

让我们考虑一个

public class Money
{
    public decimal Value { get; set; }
}

假设这是另一个类的一部分,

public class UserAccount
{
    public Money Balance { get; set; }
}

在序列化 UserAccount 上产生类似,

{
   "balance": {
       "value":  1.0
   }
}

现在我想将它转换为/从这样的 json 转换。

{
 "balance": 1.0
}

这与使用自定义格式化程序序列化 DateTime 的方式类似。 Json.Net 和 MSDN 推荐自定义格式化程序,它工作正常。但是有没有办法直接从 MoneyUserAccount 类处理这个?

编辑:澄清 Datetime 经常这样做。 例如,Datetime 的序列化应该是这样的,

{
  "Hour":"00"
  "Minutes" : "00"
   ......
}

但是不,它只是看起来像 04-12-2021 00:00:00

编辑 2:使用此 MSDN Article 中建议的自定义格式化程序有效,我希望将其用作最后一个选项。但这意味着图书馆的每个使用者都必须实施并寻找避免它的方法

解决方法

转换器可以很简单:

public class MoneyJsonConverter : JsonConverter<Money>
{
    public override Money Read(
        ref Utf8JsonReader reader,Type typeToConvert,JsonSerializerOptions options) =>
            new Money { Value = decimal.Parse(reader.GetString(),CultureInfo.InvariantCulture) };

    public override void Write(
        Utf8JsonWriter writer,Money v,JsonSerializerOptions options) =>
            writer.WriteStringValue(v.Value.ToString(CultureInfo.InvariantCulture));
}

然后

public class Money { public decimal Value { get; set; } }

public class WithMoney { public Money MyMoney { get; set; } }

static void Main(string[] args)
{
    var serializeOptions = new JsonSerializerOptions
    {
        WriteIndented = true,Converters = { new MoneyJsonConverter() }
    };


    var m = new WithMoney { MyMoney = new Money { Value = 6.66m } };

    var json = JsonSerializer.Serialize(m,serializeOptions);
    Console.WriteLine(json);

    var m2 = JsonSerializer.Deserialize<WithMoney>(json,serializeOptions);
    Console.WriteLine(m2.MyMoney.Value);
}

打印:

{
  "MyMoney": "6.66"
}
6.66

用途是

using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

并且引用是 How to write custom converters for JSON serialization (marshalling) in .NET。 这不适用于这种情况,但请注意,根据处理的类型(例如 List<T>List<DateTime>),有两种模式可用于创建自定义转换器。请参阅链接了解更多详情。