Unexpected token while deserializing an object in JsonConvert.DeserializeObject

I have the following test code:

[TestClass]
public class TestJsonDeserialize
{
    public class MyClass
    {
        [JsonProperty("myint")]
        public int MyInt { get; set; }
        [JsonProperty("Mybool")]
        public bool Mybool { get; set; }
    }

    [TestMethod]
    public void Test1()
    {
        var errors = new List<string>();
        var json1 = "{\"myint\":1554860000,\"Mybool\":false}";
        var json2 = "{\"myint\":3554860000,\"Mybool\":false}";
        var i = JsonConvert.DeserializeObject<MyClass>(json2, 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;
            }
        });
        Assert.IsTrue(errors.Count <= 1);
    }
}

Calling JsonConvert.DeserializeObject causes 2 errors. One of them is expected, and the other is not. Errors:

  • JSON integer 3554860000 is too big or small for Int32. Path 'myint', line 1, position 19.
  • Unexpected token while deserializing an object: Boolean. Path 'Mybool', line 1, position 34.

Why there is a 2nd error, although the first error is marked as processed. I have already upgraded from Newtonsoft.Json 8.0.2 to 9.0.1, but it remains. When passing the first line (json1 instead of json2), no errors occur at all.

+4
source share
1 answer

Update

1194: JsonTextReader.ParseNumber ThrowReaderError Newtonsoft , Json.NET 10.0.1.

JsonTextReader.

JsonTextReader.ParseNumber(ReadType readType, char firstChar, int initialPosition) :

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);

, ThrowReadError(), . JsonReader.TokenType JsonToken.PropertyName , , "myint". , , "Mybool", .

, ,

SetToken(JsonToken.Undefined);
ClearRecentString();

. ( , JsonToken.Undefined - .)

, Newtonsoft.

JsonReader , , , - JsonTextReader :

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

:

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
+4

Source: https://habr.com/ru/post/1668252/


All Articles