如何在Json.net中强制最小小数位?

wes*_*ton 12 c# json json.net

当我使用json.net向json写小数时,我会遇到恼人的不一致.有时它达到1 dp,有时则达到2 dp.

显然,我知道解决方案,以输出小数的一定数量的小数,如对字符串这个,但是你没有使用json.net无需编写自定义序列我猜控制.

我也知道Math.Round要强制执行最大小数位数,这个问题与强制执行最小小数位数有关.

前两个测试显示正在发生的事情,它保留声明或计算中的原始小数位数.

我发现我可以添加然后减去接下来两个测试显示工作的一小部分,但是有更清洁的方法吗?

[TestFixture]
public sealed class DecimalPlaces
{
    public class JsonType
    {
        public decimal Value { get; set; }
    }

    [Test]
    public void TwoDp()
    {
        var obj = new JsonType { Value = 1.00m };
        Assert.AreEqual("{\"Value\":1.00}", JsonConvert.SerializeObject(obj));
    }

    [Test]
    public void OneDp()
    {
        var json = new JsonType { Value = 1.0m };
        Assert.AreEqual("{\"Value\":1.0}", JsonConvert.SerializeObject(obj));
    }

    private decimal ForceMinimumDp(decimal p, int minDecimalPlaces)
    {
        decimal smallFrac = 1m/((decimal)Math.Pow(10, minDecimalPlaces));
        return p + smallFrac - smallFrac;
    }

    [Test]
    public void ForceMinimumTwoDp()
    {
        var obj = new JsonType { Value = ForceMinimumDp(1.0m, 2) };
        Assert.AreEqual("{\"Value\":1.00}", JsonConvert.SerializeObject(obj));
    }

    [Test]
    public void ForceMinimumThreeDp()
    {
        var obj = new JsonType { Value = ForceMinimumDp(1.0m, 3) };
        Assert.AreEqual("{\"Value\":1.000}", JsonConvert.SerializeObject(obj));
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 16

您可以使用自定义JSON转换器执行此操作:

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

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

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteRawValue(((decimal) value).ToString("F2", CultureInfo.InvariantCulture));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常基本的转换器.您可能需要扩展它以支持其他浮点类型,或者甚至是整数类型.

现在实例化您的序列化器并将其传递给您的自定义转换器,如下所示:

var serializer = new JsonSerializer();
serializer.Converters.Add(new DecimalJsonConverter());
Run Code Online (Sandbox Code Playgroud)