为了账号安全,请及时绑定邮箱和手机立即绑定

实现 IConvertible 的自定义数据类型的反序列化问题

实现 IConvertible 的自定义数据类型的反序列化问题

C#
犯罪嫌疑人X 2022-06-12 15:00:10
我有一堂课ChargesDetail,正在尝试反序列化 json,如下所示。在这里,我使用的数据类型是Amount.public class ChargesDetail{   public double DiscountRate { get; set; }   public Amount DiscountAmount { get; set; }}public class Amount:IConvertible {    private double _val = 0;    private int _decimal = 5;    public Amount()    {    }    public Amount(double amount): this()                {       // this.Value = amount;        _val = Math.Round(amount, _decimal);    }    #region IConvertible Members    // Implementation snipped    #endregion}我的 JSON 看起来像:{ "DiscountRate":0.0, "DiscountAmount":0.0 }我试图像这样反序列化:T result = JsonConvert.DeserializeObject<ChargesDetail>(json);它给了我一个例外,例如:从“System.Double”到“Amount”的无效转换。在 System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) at System.Double.System.IConvertible.ToType(Type type, IFormatProvider provider) at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfoculture, JsonContract contract, Type targetType)如何将 json 反序列化为此自定义数据类型?我无法删除 IConvertible,因为它在某些计算中会引发 System.StackOverflowException。我无法将 Amount 类型更改为 double 类型,bcz 有 100 多个相同类型的属性并在“Amount”类中进行计算。
查看完整描述

4 回答

?
BIG阳

TA贡献1859条经验 获得超6个赞

正如您的问题表明您正在使用json.net,您可以使用自定义Amount将您序列化为单个十进制值:JsonConverter


public class AmountConverter : JsonConverter

{

    public override bool CanConvert(Type objectType)

    {

        return objectType == typeof(Amount);

    }


    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

    {

        // Would decimal be more appropriate than double?

        var value = serializer.Deserialize<double?>(reader);

        if (value == null)

            return null;

        return new Amount(value.Value);


    }


    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

    {

        writer.WriteValue(((Amount)value).Value);

    }

}

然后,您可以将其应用于您的模型,如下所示:


[JsonConverter(typeof(AmountConverter))]

public class Amount : IConvertible

{

    private double _val = 0;

    private int _decimal = 5;


    public double Value { get { return _val; } }


    public Amount()

    {


    }


    public Amount(double amount)

        : this()

    {

        // this.Value = amount;

        _val = Math.Round(amount, _decimal);

    }


    #region IConvertible Members

    #endregion

}

或者在JsonSerializerSettings.Converters序列化和反序列化的时候加入:


var settings = new JsonSerializerSettings

{

    Converters = { new AmountConverter() },

};

var = JsonConvert.DeserializeObject<T>(json, settings);


查看完整回答
反对 回复 2022-06-12
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

在浏览您的 JSON 时。


{ "FileVersion":"11.03", "ChargesDetail":{ "DiscountRate":0.0, "DiscountAmount":0.0 } } 


public class ChargesDetail

{

   public double DiscountRate { get; set; }

   public Amount DiscountAmount { get; set; }

}


public class Amount:IConvertible 


}

在这里,您需要将 DiscountAmount 的类型更改为 double,因为您映射的结构不正确。


或者,如果您将 JSON 更改为


{ "FileVersion":"11.03", "ChargesDetail":{ "DiscountRate":0.0, "DiscountAmount":{ "DiscountAmountVar":0.0 }} }

和类


public class ChargesDetail

{

   public double DiscountRate { get; set; }

   public Amount DiscountAmount { get; set; }

}


public class Amount:IConvertible 

   public double DiscountAmountVar{get;set;}

}

然后您之前的映射将起作用。


查看完整回答
反对 回复 2022-06-12
?
炎炎设计

TA贡献1808条经验 获得超4个赞

在您的班级 Amount 中,您可以删除IConvertible并执行为:


public class Amount {

    public decimal DiscountAmountVar { get; set; }

}

有了这个和你的其他课程:


    public class ChargesDetail

{

   public decimal DiscountRate { get; set; }

   public Amount DiscountAmount { get; set; }

}

而这个 JSON:****EDIT****


string json =

            @"{""DiscountRate"":12.0, ""DiscountAmount"":{ ""DiscountAmountVar"":13.0 } }";

**编辑:刚刚意识到您需要删除一级 Json。


您应该能够制作 JsonConvert。


主要代码:


class Program

{

    static void Main(string[] args)

    {

        string json =

            @"{""DiscountRate"":12.0, ""DiscountAmount"":{ ""DiscountAmountVar"":13.0 } }";


        var converted = JsonConvert.DeserializeObject<ChargesDetail>(json);


        Console.WriteLine(converted.DiscountAmount);

    }

}



public class ChargesDetail

{

    public decimal DiscountRate { get; set; }

    public Amount DiscountAmount { get; set; }

}


public class Amount 

{

    public decimal DiscountAmountVar { get; set; }

}


查看完整回答
反对 回复 2022-06-12
?
GCT1015

TA贡献1827条经验 获得超4个赞

你的类Amount没有实现接口IConvertable



查看完整回答
反对 回复 2022-06-12
  • 4 回答
  • 0 关注
  • 187 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信