简体   繁体   English

科学记数法中的JSON.NET整数

[英]JSON.NET Integer in Scientific Notation

We are being supplied some JSON from another system that has decided it would be fun to present integers in scientific notation. 我们从另一个系统提供了一些JSON,它已经决定用科学记数法表示整数会很有趣。 As it stands JSON.NET throws an exception of: 就目前而言,JSON.NET抛出了一个例外:

Input string 9.658055e+06 is not a valid integer. 输入字符串9.658055e + 06不是有效整数。

I have been able to recreate the issue using some simple code: 我已经能够使用一些简单的代码重新创建该问题:

public class TestClass
{
    public int Value { get; set; }
}

static void Main(string[] args)
{
    var json = "{Value:9.658055e+06}";

    var xx = JsonConvert.DeserializeObject<TestClass>(json);
}

Any ideas how i can get the library to deserialize this correctly? 任何想法我如何让图书馆正确反序列化?

UPDATE: Thanks for all answers, for the record changing the type to Int64 or double would not be possible for other reasons, but the converter class has done the job 更新:感谢所有的答案,对于记录将类型更改为Int64或由于其他原因不可能加倍,但转换器类已完成工作

Two ways you can do this: 有两种方法可以做到这一点:

First and easiest is to change the type of your Value property to System.Int64 . 首先也是最简单的方法是将Value属性的类型更改为System.Int64 This would most likely "just work". 这很可能“只是工作”。

If, however, it really needs to be an int , you could do something like this: 但是,如果它确实需要是一个int ,你可以这样做:

public class TestClass
{
    [JsonConverter(typeof(JsonScientificConverter))]
    public int Value { get; set; }
}

static void Main(string[] args)
{
    var json = "{Value:9.658055e+06}";

    var xx = JsonConvert.DeserializeObject<TestClass>(json);
}

public class JsonScientificConverter : JsonConverter
{
    public override bool CanRead { get { return true; } }
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return (int)(serializer.Deserialize<System.Int64>(reader));
    }
}

Here you're reading it as a System.Int64 , but then casting it to a regular int . 在这里,您将其作为System.Int64读取,但随后将其转换为常规int So you have an int , but you have to change the class and write a custom converter, which might be overcomplicating things. 所以你有一个int ,但你必须改变类并编写一个自定义转换器,这可能会使事情过于复杂。

你需要将string反序列化为Int64等价物 -

var parsed = JsonConvert.DeserializeObject<Int64>("9.658055e+06"); //9658055

You can serialize the value to double , and access the int equivalent with another property that is hidden to the serialization (to keep the json the same): 您可以将值序列化为double ,并使用对序列化隐藏的另一个属性访问int等效项(以使json保持相同):

public class TestClass
{
    public double Value
    {
        get { return (double)IntValue; }
        set { _IntValue = (int)value; }
    }

    private int _IntValue;
    [JsonIgnore]
    public int IntValue {
        get { return _IntValue; }
        set { _IntValue = value; }
    }

}

static void Main(string[] args)
{
    var json = "{Value:9.658055e+06}";

    var xx = JsonConvert.DeserializeObject<TestClass>(json);

    Console.WriteLine(JsonConvert.SerializeObject(xx));
    Console.WriteLine(xx.IntValue); 
    Console.ReadKey();
}

As you see, the value gets correctly parsed, and when you reserialize the object, the Json stays the same, thanks to the [JsonIgnore] attribute on the IntValue property. 正如你看到的,价值被正确解析,而当你重新序列化对象,JSON的保持不变,多亏了[JsonIgnore]在属性IntValue财产。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM