我也错过了 System.Text.Json.Serialization 中的这个功能,并且曾经对每个格式化情况使用自定义 JsonConverter,但我真的不喜欢。我最好的解决方法是用更干净的方式解决这个问题 - 至少对我来说 - 使用自定义 JsonConverterAttribute。
我在 .NET6 应用程序中使用它,但根据,它也适用于 Core 3.1。
所以这个例子:
创建一个需要构造函数参数的转换器(基于已经完成的问题)。就我而言,它是格式字符串。
public class DoubleConverter : JsonConverter<double>
{
private readonly string _format;
public DoubleConverter(string format) => _format = format;
public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// Not needed for the example.
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(_format));
}
}
然后创建一个自定义 JsonAttribute。这部分使使用变得简单,因为它接受所需的构造函数参数,并使用该参数创建自定义 JsonConverter。
[AttributeUsage(AttributeTargets.Property)]
public class DoubleSerializationStringFormatAttribute : JsonConverterAttribute
{
private readonly string _format;
public DoubleSerializationStringFormatAttribute(string format) => _format = format;
public override JsonConverter CreateConverter(Type typeToConvert)
{
if (typeToConvert != typeof(double))
{
throw new ArgumentException(
$"This converter only works with double, and it was provided {typeToConvert.Name}.");
}
return new DoubleConverter(_format);
}
}
现在该属性可以用于任何属性:
public class DataClass
{
[DoubleSerializationStringFormat("N2")]
public double Prop1 { get; set; }
[DoubleSerializationStringFormat("N5")]
public double Prop2 { get; set; }
}
最后我可以序列化 DataClass 实例:
var data = new DataClass() {Prop1 = 10.5678, Prop2 = 3.14159267};
var serialized = JsonSerializer.Serialize(data);
Console.Write(serialized);
我得到了根据指定格式序列化的数字:
{
"Prop1":"10.57",
"Prop2":"3.14159"
}