简体   繁体   English

NewtonSoft反序列化中的处理错误不起作用

[英]Handling Error in NewtonSoft Deserialization doesn't work

I'm trying to handle deserialization error, but even if I'm able to reach error handling function and set Handled property to true then error is throwing to the main function. 我正在尝试处理反序列化错误,但是即使我能够访问错误处理功能并将Handled属性设置为true,也会将错误抛出给主函数。

Models: 楷模:

public class PriceValidity
{
    public Date EndDate { get; set; }

    public Date StartDate { get; set; }

    [OnError]
    internal void OnError(StreamingContext context, ErrorContext errorContext)
    {
        errorContext.Handled = true;
    }
}

public class Date
{
    [JsonProperty("$date")]
    public DateTime Value { get; set; }
}

Calling deserializer: 调用解串器:

private void ParseMessage<T>(string message) where T: new()
{
    var result = new T();
    var jsonSerializer = new Newtonsoft.Json.JsonSerializer();

    using (var reader = new StringReader(message))
    using (var jsonReader = new JsonTextReader(reader))
    {
        result = jsonSerializer.Deserialize<T>(jsonReader);
    };
}

JSON: JSON:

{  
   "StartDate":{  
      "$date":"2018-05-07T00:00:00.000Z"
   },
   "EndDate":{  
      "$date":{  
         "$numberLong":"253402214400000"
      }
   }
}

Error: 错误:

After parsing a value an unexpected character was encountered: :. 解析值后,遇到意外字符::。 Path 'EndDate.$date', 路径“ EndDate。$ date”,

I don't want to handle also $numberLong scenario but just skip it. 我不想同时处理$ numberLong场景,而只是跳过它。

Not an answer but a workaround: Move the error handling to serializer options: 不是答案,而是一种解决方法:将错误处理移至序列化器选项:

    private T ParseMessage<T>(string message) where T : new() => 
        JsonConvert.DeserializeObject<T>(message, new JsonSerializerSettings
    {
        Error = (object sender, ErrorEventArgs args) => { args.ErrorContext.Handled = true; }
    });

From Chetan Ranpariya's comment: 来自Chetan Ranpariya的评论:

Having OnError in entity class is useful when there is a change of exception being thrown from the Entity class itself as explained for the Roles property of the PersonError class here: https://www.newtonsoft.com/json/help/html/SerializationErrorHandling.htm 当从Entity类本身引发异常更改时,在Entity类中具有OnError很有用,如此处有关PersonError类的Roles属性所述: https ://www.newtonsoft.com/json/help/html/SerializationErrorHandling .htm

Finally I found solution. 终于我找到了解决方案。 To handle such scenario I've had to create Json Converter. 为了处理这种情况,我不得不创建Json Converter。

public class JMSDateTimeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            JToken token = JToken.Load(reader);

            if (token.Type == JTokenType.Object && GetAllChildresnCount(token) == 2)
            {
                return token.ToObject(objectType);
            }
            else
            {
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        finally
        {
        }
    }

    private int GetAllChildresnCount(JToken token)
    {
        var container = token as JContainer;

        if (container == null)
        {
            return 0;
        }

        var count = container.Count;

        foreach (JToken subToken in container)
        {
           count += GetAllChildresnCount(subToken);
        }

        return count;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

Now works fine. 现在工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM