将 json 属性反序列化为 bool 或 double

Fab*_*tos 1 .net c# json.net

我有以下 json:

"rates": {
        "AT": {
            "country": "Austria",
            "standard_rate": 20.00,
            "reduced_rate": 10.00,
            "reduced_rate_alt": 13.00,
            "super_reduced_rate": false,
            "parking_rate": 12.00
        },
        "DK": {
            "country": "Denmark",
            "standard_rate": 25.00,
            "reduced_rate": false,
            "reduced_rate_alt": false,
            "super_reduced_rate": false,
            "parking_rate": false
        },
}
Run Code Online (Sandbox Code Playgroud)

我有以下类来反序列化 json:

    public string country { get; set; }
    public double standard_rate { get; set; }
    //public string reduced_rate { get; set; }
    private double _reduced_rate;

    public double reduced_rate
    {
        get { return _reduced_rate; }
        set
        {
            bool isDouble = Double.TryParse(value.ToString(), out _reduced_rate);
            if (isDouble)
                _reduced_rate = value;
            else
                _reduced_rate = 0.0;
        }
    }

    public string reduced_rate_alt { get; set; }
    public string super_reduced_rate { get; set; }
    public string parking_rate { get; set; }
Run Code Online (Sandbox Code Playgroud)

当 的值为reduce_ratea时false,我想设置 a 0.0else 的双精度值。但在 set 方法中永远不会进入else.

有其他方法可以解决这种情况吗?

Ňɏs*_*arp 5

处理此问题的一种方法是定义reduced_rate_alt为字符串,然后定义一个新属性,该属性读取并尝试将其解析为 getter 中的值。这可以工作,但你有几个类似的属性,并且由于使用 JSON.NET,相同的转换器应该适用于所有这些属性,我将手动转换这些属性:

[JsonConverter(typeof(RateJsonConverter))]
public decimal reduced_rate_alt { get; set; }
Run Code Online (Sandbox Code Playgroud)

用该属性装饰每个可能返回 false 的属性。这表明JSON.NET您正在提供反序列化该属性的代码。当您这样做时,您可能还想用 来修复属性名称[JsonProperty]

规则/转换实现只是简单地使用 0 作为false其他值。只要所有属性的转换规则都相同,您就可以对每个属性使用相同的转换器。我还将类型更改为十进制,这可能更适合这些。

public class RateJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {   // name used in a previous answer
        return (objectType == typeof(VRate));
    }

    public override object ReadJson(JsonReader reader, Type objectType, 
                                object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        decimal d = 0M;

        Decimal.TryParse(token.ToString(), out d);        
        return d;
    }

    public override void WriteJson(JsonWriter writer, object value,
                    JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

测试:

var rates = JsonConvert.DeserializeObject<VRates>(jstr).rates;

foreach (KeyValuePair<string, VRate> kvp in rates)
{
    Console.WriteLine("key: {0} ({1}), reduced alt rate: {2}", kvp.Key, 
        kvp.Value.country,
        kvp.Value.reduced_rate_alt.ToString("F2"));
    kvp.Value.VTag = kvp.Key;
}
Run Code Online (Sandbox Code Playgroud)

前几个的输出:

关键:AT(奥地利),降低的替代率:13.00
关键:BE(比利时),降低的替代率:6.00
关键:BG(保加利亚),降低的替代率:0.00
关键:CY(塞浦路斯),降低的替代率:5.00
关键: CZ(捷克共和国),降低的替代率:10.00
密钥:DK(丹麦),降低的替代率:0.00

BG 和 DK 为 false,转换为 0,而其他则具有 JSON 中列出的速率。