【问题标题】:Cannot deserialize exponential numericals with Json.Net无法使用 Json.Net 反序列化指数数值
【发布时间】:2015-01-27 03:25:04
【问题描述】:

我正在解析来自证券交易所市场的一些值,并且我的解析器工作正常,但在某些情况下,我连接的 API 中的数值返回如下内容:

{
   "stock_name": "SOGDR50",
   "price": "6.1e-7"
}

在大多数请求中,price 以小数形式出现(例如:0.00757238)并且一切正常,但是当 price 是指数表示时,我的解析器会中断。

我正在使用Json.Nethttp://www.newtonsoft.com/json

我的代码是:

T response = JsonConvert.DeserializeObject<T>(jsonResult);

我玩过JsonSerializerSettings,但没有想出任何解决方案。我可以手动解析有问题的数字,但我需要将响应自动反序列化为正确的对象,具体取决于调用的 API 方法。

关于如何解决这个问题的任何想法?

编辑 1:

public class StockResponse
{
    [JsonConstructor]
    public StockResponse(string stock_name, string price)
    {
        Stock_Name = stock_name;
        Price = Decimal.Parse(price.ToString(), NumberStyles.Float);
    }

    public String ShortName { get; set; }
    public String LongName { get; set; }
    public String Stock_Name{ get; set; }
    public Decimal Price { get; set; }
    public Decimal Spread { get; set; }
}

【问题讨论】:

    标签: c# json parsing json.net


    【解决方案1】:

    JSON.NET 包含[JsonConstructor] 的属性,您可以将其附加到自定义构造函数。有了它,你可以这样做:

    [JsonConstructor]
    //The names of the parameters need to match those in jsonResult
    public StockQuote(string stock_name, string price)
    {
        this.stock_name = stock_name;
        //You need to explicitly tell the system it is a floating-point number
        this.price = Decimal.Parse(price, System.Globalization.NumberStyles.Float);
    }
    

    编辑:

    除上述之外,使用[JsonObject] 属性标记您的类。这是序列化和反序列化所需要的。我能够使用以下方法成功序列化和反序列化:

    class Program
    {
        static void Main(string[] args)
        {
            var quote = new StockQuote("test", "6.1e-7");
            string data = JsonConvert.SerializeObject(quote);
            Console.WriteLine(data);
    
            StockQuote quoteTwo = JsonConvert.DeserializeObject<StockQuote>(data);
            Console.ReadLine();
        }
    }
    
    [JsonObject]
    public class StockQuote
    {
        //If you want to serialize the class into a Json, you will need the
        //JsonProperty attributes set
        [JsonProperty(PropertyName="name")]
        public string Name { get; set; }
        [JsonProperty(PropertyName="price")]
        public decimal Price { get; set; }
    
        [JsonConstructor]
        public StockQuote(string name, string price)
        {
            this.Name = name;
            this.Price = Decimal.Parse(price, System.Globalization.NumberStyles.Float);
        }
    }
    

    【讨论】:

    • 感谢您的回答!我在您的示例之后添加了一个自定义构造函数,还添加了一个空构造函数,添加了断点,但是对于有问题的值,它永远不会到达这些构造函数,它会立即从该行 T response = JsonConvert.DeserializeObject&lt;T&gt;(jsonResult); 引发异常。对于正常值,它通过自定义构造函数。有什么想法吗?
    • 你反序列化的类是什么样的?您可以编辑您的问题以包含该课程吗?
    • 好的我想我明白了,我没有复制你的例子,我应该将price 传递为string,现在它进入构造函数但使用点而不是逗号来分隔小数点所以它抛出一个异常,因为它无法解析它,这是现在唯一的问题。
    • 要解决这个问题,您可以找出所传递数字的 System.Globalization.CultureInfo 是什么(听起来像是德语?)并将该对象传递给 Decimal.Parse() 或者您可以蛮力使用String.Replace() 方法(我不推荐这个,但它是一个选项)
    • Parse 命令中添加`CultureInfo.InvariantCulture` 可以解决问题。非常感谢您提供如此宝贵的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2023-03-19
    • 2017-04-10
    • 2020-03-09
    • 1970-01-01
    相关资源
    最近更新 更多