RavenDB源代码中的ParseBigInteger FormatException

时间:2014-11-27 11:57:19

标签: c# wpf parsing ravendb biginteger

在我们的WPF应用程序中,我们有输入验证。其中一个输入值是十进制,它允许最多28位数(如999999999999999999999999999)。还有一个9,它给出了验证错误反馈,但28 9的工作按预期进行。

但是,当我们尝试将其保存到RavenDB时,它会提供一个BigIntegerParse FormatException,但我无法找出原因。我认为BigInteger的大小几乎是无限的(如果我没弄错,它的字节最大值等于Integer.MAX_VALUE,尽管我不确定)。不过,你会假设一个BigInteger Parse可以毫不费力地将一个28 9的字符串转换成一个BigInteger。

这是StackTrace的一部分:

System.FormatException: The value could not be parsed.
   at System.Numerics.BigNumber.ParseBigInteger(String value, NumberStyles style, NumberFormatInfo info)
   at Raven.Imports.Newtonsoft.Json.JsonTextReader.ParseNumber() in c:\Builds\RavenDB-Stable-3.0\Imports\Newtonsoft.Json\Src\Newtonsoft.Json\JsonTextReader.cs:line 1288
   at Raven.Imports.Newtonsoft.Json.JsonTextReader.ParseValue() in c:\Builds\RavenDB-Stable-3.0\Imports\Newtonsoft.Json\Src\Newtonsoft.Json\JsonTextReader.cs:line 1010
   at Raven.Imports.Newtonsoft.Json.JsonTextReader.ReadInternal() in c:\Builds\RavenDB-Stable-3.0\Imports\Newtonsoft.Json\Src\Newtonsoft.Json\JsonTextReader.cs:line 383
   at Raven.Imports.Newtonsoft.Json.JsonTextReader.Read() in c:\Builds\RavenDB-Stable-3.0\Imports\Newtonsoft.Json\Src\Newtonsoft.Json\JsonTextReader.cs:line 304
   at Raven.Json.Linq.RavenJObject.Load(JsonReader reader) in c:\Builds\RavenDB-Stable-3.0\Raven.Abstractions\Json\Linq\RavenJObject.cs:line 251
   at Raven.Json.Linq.RavenJObject.Load(JsonReader reader) in c:\Builds\RavenDB-Stable-3.0\Raven.Abstractions\Json\Linq\RavenJObject.cs:line 211
   at Raven.Json.Linq.RavenJObject.Load(JsonReader reader) in c:\Builds\RavenDB-Stable-3.0\Raven.Abstractions\Json\Linq\RavenJObject.cs:line 211
   at Raven.Json.Linq.RavenJArray.Load(JsonReader reader) in c:\Builds\RavenDB-Stable-3.0\Raven.Abstractions\Json\Linq\RavenJArray.cs:line 139
   ...

我查找了第一个StackTrace行(c:\Builds\RavenDB-Stable-3.0\Imports\Newtonsoft.Json\Src\Newtonsoft.Json\JsonTextReader.cs:line 1288)的源代码,并在此处找到了它:RavenDB JsonTextReader

第1288行具有以下代码:

1284        else if (parseResult == ParseResult.Overflow)
1285        {
1286    #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE)
1287            string number = _stringReference.ToString();
{1288}          numberValue = BigInteger.Parse(number, CultureInfo.InvariantCulture);
1289            numberType = JsonToken.Integer;
1290    #else
1291            // todo - validate number was a valid integer to make sure overflow was the reason for failure
1292            throw JsonReaderException.Create(this, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
1293    #endif
1294        }

所以,我的问题:这个Parser在RavenDB源代码中可以容纳的最大值是多少?如果我知道max我可以调整验证类,我们用它来设置最大值,而不是默认的十进制最大值。 (我们使用RavenDB来保存事件状态,我们的项目使用CQRS架构。)

1 个答案:

答案 0 :(得分:1)

看起来问题在于RavenDb如何反序列化JSON。 这是一个样本。让我们声明样本模型:

public class Foo
{
    public decimal Bar { get; set; }
}

...并将其序列化为JSON:

var serializer = new JsonSerializer();
var sb = new StringBuilder();
var foo = new Foo
{
    Bar = 9999999999999999999999999999M
};

using (var textWriter = new StringWriter(sb))
using (var jsonWriter = new JsonTextWriter(textWriter))
{
    serializer.Serialize(jsonWriter, foo);
}

Debug.WriteLine(sb);

输出将包含:

  

{ “酒吧”:9999999999999999999999999999.0}

请注意,字符串表示中有一个小数部分。 当然,如果您尝试将此值解析为BigInteger(如RavenDb那样),您将获得FormatException,因为此字符串对BigInteger无效。

你能在这做什么? 老实说,我不知道......可能是,如果 是一个大整数,最好将数据存储在模型中BigInteger