を変更した後Json.NETの独自のバージョンを再コンパイルすることができます(「あなたはドンと仮定独自のカスタムバージョンのJson.NETソースをコンパイルするという手間を掛けたい)、独自のカスタムJsonConverterクラスを作成して小数点、浮動小数点、および倍精度の値を扱うことができます。私が使用しているバージョンは次のとおりです。
class DecimalJsonConverter : JsonConverter
{
public DecimalJsonConverter()
{
}
public override bool CanRead
{
get
{
return false;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(decimal) || objectType == typeof(float) || objectType == typeof(double));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (DecimalJsonConverter.IsWholeValue(value))
{
writer.WriteRawValue(JsonConvert.ToString(Convert.ToInt64(value)));
}
else
{
writer.WriteRawValue(JsonConvert.ToString(value));
}
}
private static bool IsWholeValue(object value)
{
if (value is decimal)
{
decimal decimalValue = (decimal)value;
int precision = (Decimal.GetBits(decimalValue)[3] >> 16) & 0x000000FF;
return precision == 0;
}
else if (value is float || value is double)
{
double doubleValue = (double)value;
return doubleValue == Math.Truncate(doubleValue);
}
return false;
}
}
これは、decimal型の値の精度を保持します。上記のコードを使用するように、いずれの場合においても
private static bool IsWholeValue(object value)
{
if (value is decimal)
{
decimal decimalValue = (decimal)value;
return decimalValue == Math.Truncate(decimalValue);
}
else if (value is float || value is double)
{
double doubleValue = (double)value;
return doubleValue == Math.Truncate(doubleValue);
}
return false;
}
:あなたは小数値の精度を無視することを好む場合は、IsWholeValue()関数の小数部分がフロート/ダブル部分と同じように動作させることができシリアライザを次のように呼び出してください:
string json = JsonConvert.SerializeObject(value, new DecimalJsonConverter())