aktualisieren
als Issue 1194: JsonTextReader.ParseNumber leads to error after ThrowReaderError Berichtet und dann aktuellen Build als nicht reproduzierbar durch Newtonsoft geschlossen, die anschließend als Json.NET 10.0.1 veröffentlicht wurde.
Original-Antwort
Dies kann ein Fehler in JsonTextReader
sein.
In JsonTextReader.ParseNumber(ReadType readType, char firstChar, int initialPosition)
es die folgenden Logik ist, etwas vereinfacht:
else if (readType == ReadType.ReadAsInt32)
{
// Snip
int value;
ParseResult parseResult = ConvertUtils.Int32TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out value);
if (parseResult == ParseResult.Success)
{
numberValue = value;
}
else if (parseResult == ParseResult.Overflow)
{
throw ThrowReaderError("JSON integer {0} is too large or small for an Int32.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
}
else
{
throw ThrowReaderError("Input string '{0}' is not a valid integer.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString()));
}
}
numberType = JsonToken.Integer;
}
// Snip
// Finally, after successfully parsing the number
ClearRecentString();
// index has already been updated
SetToken(numberType, numberValue, false);
An der Stelle, die Ausnahme von ThrowReadError()
geworfen wird, hat der Strom vorbei an der Position zu großen ganzen Zahl vorgeschoben worden ist. Der Wert für JsonReader.TokenType
wurde jedoch nicht aktualisiert und gibt weiterhin JsonToken.PropertyName
für das letzte erfolgreich analysierte Token zurück, nämlich den Namen "myint"
. Später, nachdem die Ausnahme verschluckt und ignoriert wurde, führt die Inkonsistenz zwischen der Stream-Position und dem aktuellen Tokenwert dazu, dass der Eigenschaftsname "Mybool"
übersprungen wird, was zum zweiten Fehler führt.
Wenn im Debugger, wenn die Ausnahme, die ich
SetToken(JsonToken.Undefined);
ClearRecentString();
Dann kann der Rest der Datei manuell ausgelöst wird
rufen erfolgreich analysiert werden. (Ich bin mir nicht sicher
JsonToken.Undefined
ist die richtige Wahl hier.)
Sie möchten vielleicht report an issue zu Newtonsoft.
Da die JsonReader
nicht in die Fehlerbehandlungsroutine übergeben, die nur Abhilfe ich finden konnte, ist JsonTextReader
Unterklasse wie folgt:
public class FixedJsonTextReader : JsonTextReader
{
public FixedJsonTextReader(TextReader reader) : base(reader) { }
public override int? ReadAsInt32()
{
try
{
return base.ReadAsInt32();
}
catch (JsonReaderException)
{
if (TokenType == JsonToken.PropertyName)
SetToken(JsonToken.None);
throw;
}
}
}
Und dann tun:
var errors = new List<string>();
var json2 = "{\"myint\":3554860000,\"Mybool\":false}";
using (var reader = new FixedJsonTextReader(new StringReader(json2)))
{
var settings = new JsonSerializerSettings
{
Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
Debug.WriteLine(args.ErrorContext.Error.Message);
errors.Add(args.ErrorContext.Error.Message);
args.ErrorContext.Handled = true;
}
};
var i = JsonSerializer.CreateDefault(settings).Deserialize<MyClass>(reader);
}
Assert.IsTrue(errors.Count <= 1); // Passes
Die workouround arbeitet für mein Testprojekt. Danke vielmals. Ich habe jetzt ein Problem auf GitHub gemeldet, wie du es vorgeschlagen hast. – huha