如何对具有无效值的属性使用默认值 JSON.net



我正在使用Newtonsoft JSON库来反序列化来自Web服务的响应。问题是某些字段包含无效的值。例如,一条记录上的一个字段包含"T",表示应该是数字的字段。我想做的是让无效字段的值为 null 或其他默认值。我的所有属性都定义为可为空,因此如果它们默认为 null 也没关系。

有没有办法做到这一点?我尝试创建自定义 JsonConverters,但我不希望为每种类型定义 JsonConverter。如果可能的话,我想为所有字段设置null,如果该属性的值无效(例如数字类型的"T"(。

我已经查看了 OnError 事件处理程序,但这似乎在错误时丢弃了整条记录。我不想丢弃任何记录。我只想将无效属性的值设置为空。

这可能吗?我寻找了很多答案,我没有找到另一个试图这样做的问题,但是如果我忽略了现有问题,请告诉我。

谢谢你的帮助。

您可以为所有可为 null 的类型创建一个JsonConverter,该类型尝试在非 null 时将相应的 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() } };

如果 JSON 本身格式不正确且无法读取,转换器仍将抛出异常(从调用 JToken.Load()(。 仅当 JSON 值在加载后无法转换为适当的类型时,它才会吞噬异常。

尝试在反序列化上设置错误委托,并通过设置 args 来处理您要查找的错误。ErrorContext.Handle = 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;
            }
    });
}

相关内容

  • 没有找到相关文章