c# - 如何为自定义 JsonConverter 设置 FloatParseHandling.Decimal?

标签 c# .net json.net jsonconverter

如何为自定义 JsonConverter 设置 FloatParseHandling.Decimal?

我们有一个结构体 DecimalDbValue,它在内部只保存一个我想对其所有类型进行反/序列化的十进制字段。

它使用魔数(Magic Number) (decimal.MinValue) 来指示“空”值。它是在具有可为空值类型的 .net 2.0 之前创建的!

这是我们结构的精简版本:

    [Serializable]
    [JsonConverter(typeof(DecimalDbValueJsonConverter))]
    public struct DecimalDbValue : ISerializable
    {
        private readonly Decimal _decValue;

        public DecimalDbValue(
            decimal init)
        {
            _decValue = init;
        }

        [JsonConstructor]
        public DecimalDbValue(
            decimal? init)
        {
            if (init.HasValue)
                _decValue = init.Value;
            else
                _decValue = decimal.MinValue;
        }

        private DecimalDbValue(
            SerializationInfo objSerializationInfo,
            StreamingContext objStreamingContext)
        {
            _decValue = objSerializationInfo.GetDecimal("value");
        }

        public bool IsNotNull
        {
            get
            {
                return !IsNull;
            }
        }

        public bool IsNull
        {
            get
            {
                return _decValue.Equals(Decimal.MinValue);
            }
        }

        public Decimal Value
        {
            get
            {
                return _decValue;
            }
        }

        public void GetObjectData(
            SerializationInfo info,
            StreamingContext context)
        {
            info.AddValue("value", _decValue);
        }
}

我创建了一个 JsonConverter:
    class DecimalDbValueJsonConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(DecimalDbValue) == objectType;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var value = reader.Value == null ? (decimal?)null : Convert.ToDecimal(reader.Value);
            return new DecimalDbValue(value);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var dbValue = (DecimalDbValue)value;
            if (dbValue.IsNull)
                writer.WriteNull();
            else
                writer.WriteValue(dbValue.Value);
        }
    }

并设置属性 [JsonConverter(typeof(DecimalDbValueJsonConverter))]在 DecimalDbValue 结构上

我添加了一个测试:
        [Test]
        public void TestMaxDecimalDbValue()
        {
            var s = new DecimalDbValue(decimal.MaxValue);
            var json = JsonConvert.SerializeObject(s, Formatting.Indented);
            var x = JsonConvert.DeserializeObject<DecimalDbValue>(json);

            Assert.AreEqual(s, x);
        }

但它抛出:System.OverflowException : Value was either too large or too small for a Decimal.
我如何设置 FloatParseHandling.Decimal对于 JsonConverter?如何使其适用于 MaxValue还有?有没有其他办法?

实际上我想让它像 decimal? 一样序列化/反序列化(可为空的十进制)

谢谢

最佳答案

这似乎是不可能的。

因此我完全删除了 JsonConverter。

在结构上设置此属性:

[JsonObject(MemberSerialization.OptIn)]

以及构造函数上的这个:
 [JsonConstructor]
    public DecimalDbValue(
        decimal? init) //IMPORTANT: if you change the name of init - rename the JsonProperty below too - you might break all existing json out there thou!

以及 get 属性上的这个:
[JsonProperty("init")]
    public Decimal Value
    {
        get
        {
            return _decValue;
        }
    }

不幸的是,这会使 json 膨胀:
{
    "init": 79228162514264337593543950335.0
}

关于c# - 如何为自定义 JsonConverter 设置 FloatParseHandling.Decimal?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59625363/

相关文章:

c# - 如何避免捕获变量?

c# - 努力解决方法和类的交互方式

c# - 为一个参数指定多个接口(interface)

c# - 如何将datagridview列更改为int

c# - 从 IEnumerable foreach 循环中获取值

c# - 当 json 具有更深一层的数组时,如何使用 C# 将 Json 字符串转换为在 Json.Net 中具有列表的类

c# - 在 C# 中将过滤器与 JsonPath 一起使用

c# - 多客户端 RPC

c# - 为什么在 MVP 中使用 Presenter 接口(interface)?

.net - 我可以从 JavaScript (JScript) 或 VBScript 使用 .NET Framework 吗?