Как я могу заставить минимальное количество знаков после запятой в Json.net?

Я получаю раздражающую непоследовательность, когда пишу десятичные дроби в json, используя json.net - ... Иногда это 1 dp, иногда 2.

очевидно, я знаю решения для вывода десятичных знаков в строки с определенным количеством десятичных знаков, таких как этой, но у вас нет этого контроля, используя 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));
    }
}

1 ответов


вы можете сделать это с помощью пользовательского конвертера 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));
    }
}

Это очень простой конвертер. Возможно, вам придется расширить его для поддержки других типов с плавающей запятой или, возможно, даже целочисленных типов.

Теперь создайте экземпляр своего сериализатора и передайте ему свой пользовательский конвертер, например:

var serializer = new JsonSerializer();
serializer.Converters.Add(new DecimalJsonConverter());