How to use default value for JSON.net for properties with invalid values

I am using the Newtonsoft JSON library to deserialize a response from a web service. The problem is that some of the fields contain invalid values. For example, one field in one record contained a “T” for the field, which should be numeric. What I would like to do is to have values ​​for fields that are invalid, zero, or some other default value. All my properties are defined as nullable, so it’s ok if they default to null.

Is there any way to do this? I tried to create custom JsonConverters, but I would prefer not to define JsonConverter for each type. If possible, I would like to set all fields to null if the value for this property is not valid (for example, "T" for a numeric type).

I looked at the OnError event handler, but this seems to discard the entire error record. I do not want to discard records. I just would like the value of the invalid properties to be null.

Is it possible? I searched a lot for answers, and I did not find another question that tried to do this, but please let me know if I missed an existing question.

Thank you for your help.

+4
source share
2 answers

JsonConverter , JSON , null:

public class NullableTypeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return Nullable.GetUnderlyingType(objectType) != null;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var underlyingType = Nullable.GetUnderlyingType(objectType);
        if (underlyingType == null)
            throw new JsonSerializationException("Invalid type " + objectType.ToString());
        var token = JToken.Load(reader);
        try
        {
            return token.ToObject(underlyingType, serializer);
        }
        catch (Exception ex)
        {
            // Log the exception somehow
            Debug.WriteLine(ex);
            return null;
        }
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

.

var settings = new JsonSerializerSettings { Converters = new[] { new NullableTypeConverter() } };

- ( JToken.Load()), JSON . , JSON .

+2

Error Deserialize , , args.ErrorContext.Handled = true. :

public class TestClass1
{
    public string Id { get; set; }
    public int Height { get; set; }
}

public class TestClass2
{
    public string Id { get; set; }
    public string Height { get; set; }
}

[TestMethod]
public void Test()
{
    TestClass2 x = new TestClass2() { Id = "1", Height = "something" };
    string str = JsonConvert.SerializeObject(x);

    JsonConvert.DeserializeObject<TestClass1>(str, new JsonSerializerSettings()
        {
            Error = delegate(object sender, ErrorEventArgs args)
            {
                if (args.ErrorContext.Error.GetType().FullName == typeof(JsonReaderException).FullName)
                    args.ErrorContext.Handled = true;
            }
    });
}
+1

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


All Articles