19

我正在使用 Newtonsoft.Json.JsonSerializer 序列化小数。

如何将其设置为序列化只有 1 个小数位的十进制数字以在末尾使用 0。

即 3.5 序列化为“3.50”?

4

2 回答 2

39

您必须编写自己的自定义JsonConverter并使用它来拦截decimal类型,以便您可以更改它的序列化方式。这是一个例子:

public class DecimalFormatConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(decimal));
    }

    public override void WriteJson(JsonWriter writer, object value, 
                                   JsonSerializer serializer)
    {
        writer.WriteValue(string.Format("{0:N2}", value));
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override object ReadJson(JsonReader reader, Type objectType,
                                 object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();    
    }
}   

要使用它,只需将此自定义转换器的新实例传递给该SerializeObject方法:

var json = JsonConvert.SerializeObject(yourObject, new DecimalFormatConverter());
于 2013-07-26T02:41:34.237 回答
22

接受的答案是正确的,但扩展了对接受的答案的评论:

如果您希望 JSON 中的小数是数字而不是字符串,则需要使用WriteRawValue和使用:0.00而不是:N2字符串格式(N2包括千位分隔符逗号和其他会破坏 JSON 的文化特定数字格式)

public class DecimalFormatConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(decimal);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteRawValue($"{value:0.00}");
    }

    public override bool CanRead => false;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

这是输出与接受的答案相比的差异。

# writer.WriteRawValue($"{value:0.00}");
{
    "MyDecimal": 3.50,
    "MyBiggerDecimal": 12345.50
}

# writer.WriteValue($"{value:N2}");
{
    "MyDecimal": "3.50",
    "MyBiggerDecimal": "12,345.50"
}

注意 - 接受的答案对于 OP 的特定问题是正确的,即 serialize 3.5to "3.50",但我到这里想要序列化3.5​​to 3.50(不带字符串引号)。

于 2019-05-03T13:53:37.783 回答