2014-11-27 1 views
0

우리 WPF 애플 리케이션에서 입력 유효성 검사가 있습니다. 입력 값 중 하나는 십진수이며 최대 값은입니다. 한 번 더 9 그리고 그것은 유효성 오류 피드백을 제공하지만 28 9의 의도대로 작동합니다.ParseBigInteger FormatException RavenDB 소스 코드에서

그러나 RavenDB에 저장하려고하면 BigIntegerParse가 FormatException이고 이유를 알 수 없습니다. BigInteger의 크기가 거의 무한하다고 생각했습니다. (확실하지는 않지만 실수로 바이트 길이가 Integer.MAX_VALUE과 같습니다). 그래도 BigInteger Parse가 28 9가있는 문자열을 BigInteger로 변환하는 데 문제가 없다고 가정합니다. 내가 처음 스택 트레이스 라인 (c:\Builds\RavenDB-Stable-3.0\Imports\Newtonsoft.Json\Src\Newtonsoft.Json\JsonTextReader.cs:line 1288)의 소스 코드를보고 여기를 발견했습니다

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 
    ... 

: 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  } 

그래서, 내 질문이 파서는 RavenDB 소스 코드에 저장할 수있는 최대 값은 무엇입니까? 최대 값을 알고 있다면 유효성 검사 클래스를 조정하여 기본 십진수의 max 대신 max로 설정할 수 있습니다. (우리는 RavenDB를 사용하여 Event-states를 저장하고 프로젝트는 CQRS 아키텍처를 사용합니다.)

+0

'parseResult'는 분명히 게시 한 세그먼트의 소스 코드 어딘가에서 온 것입니다. 그것의 기원으로 되돌아가? –

+0

@ J.Steen 어쩌면 꽤 분명하지만 어쩌면? 나는 RavenDB의 소스 코드를 디버깅 할 수 없으며 1288 행은 꽤 솔직하게 보인다. 'BigInteger.Parse'로 문자열을 구문 분석하지만 FormatException을 제공합니다. 아니면 그 길을 따라 소스 코드에서 문자열이 변경되었을 수도 있다는 뜻입니까? (더 이상 구문 분석의 시점에서 289가 아닙니다.) (이 행 1288은 오류의 가장 깊은 곳으로, 꼭대기가 아닙니다.) –

+0

'parseResult'는 어딘가에서 왔다고 말했지만, 분명하지 않다고 말했습니다. ;)'BigInteger.Parse'는 실제 유효성 검사가 아니며 아마 여러분을 쫓아 버릴 것입니다. 유효성 검사는 이미 완료되었으며'parseResult' 변수는 코드의 이전 위치에서 그 유효성 검사 결과입니다. –

답변

1

RavenDb가 JSON을 deserialize하는 방법에 문제가있는 것처럼 보입니다. 다음은 샘플입니다. 의 샘플 모델을 선언하자

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처럼)으로 구문 분석하려고하면 BigInteger에 대해이 문자열이 유효하지 않기 때문에 FormatException이 표시됩니다.

여기서 수행 할 수있는 작업은 무엇입니까? 솔직히 모르겠습니다 ... 모델에 데이터를 BigInteger으로 저장하는 것이 더 좋습니다. 이면 큰 정수입니까?

+0

내 데이터에는 십진수 (소득)입니다. 물론 누구나 28 세 9 세를 1 년 소득으로 넣을 사람이 누구인지는 분명하지 않습니다.) 테스트를하는 동안 우리는 그것을 발견했습니다. 입력으로 작은 크기를 허용 할 수 있다고 생각했기 때문에 (너무 큰) 입력에서이 BigInteger FormatException을 제공 할 수 없습니다. 그러나 우리의 데이터에서 소득을 BigInteger로 만드는 것은 좋은 해결책이 아닙니다. –

+0

@KevinCruijssen : 테스트에 합격 한 가치가 더 적습니까? – Dennis

+0

예, '10000' 또는'17000000.00'과 같은 일반적인 값을 사용하면 모든 것이 의도 한대로 작동하며 예외가 발생하지 않습니다. –