How can I force a minimum number of decimal places in Json.net?
You can do it with a custom JSON converter:
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));
}
}
This is a very basic converter. You may need to extend it to support other floating-point types, or perhaps even integer types too.
Now instantiate your serialiser and pass it your custom converter, like so:
var serializer = new JsonSerializer();
serializer.Converters.Add(new DecimalJsonConverter());
I know this is an old question but I had a similar problem where I am automating the verification of a JSON API responses, where I needed to force a minimum of 3 decimal places. I thought that I'd leave my somewhat generic solution here as it may help someone and save them time if they have a similar issue.
The actual JSON returned zero padded to 3 decimal places if there were only 1 or 2 digits after the decimal place.
My expected verification data then needed to also zero pad e.g.
10.3 pad to 10.300
10.34 pad to 10.340
10.345 leave as is as will match the actual
I built up my expected in the following manner, which solved the problem for me:
public static decimal GetRate(
string fromCurrency,
string toCurrency,
decimal rawRate,
decimal margin)
{
if (fromCurrency == toCurrency) return 1m;
var _rate = Math.Round(rawRate * (1 + (margin / 100)), 7);
var _numberOfPlacesAfterDecimalPlace = _rate.ToString().Split('.')[1].Length;
// NOTE: Software API response stores precision value to 3 decimal places, need to cater
// for that here for currency pairs where the resulting rate has less than 3 decimal places.
// This will zero pad the result after the decimal place to 3 places
if (_numberOfPlacesAfterDecimalPlace >= 3) { return _rate; }
return Decimal.Parse(string.Format("{0:F3}", _rate));
}
My solution avoided the need for me to write a custom JSON converter for this particular issue.