json.net在序列化时限制maxdepth

前端之家收集整理的这篇文章主要介绍了json.net在序列化时限制maxdepth前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们将Asp.Net WebAPI与实体框架(延迟加载)一起使用,并在将数据返回给客户端之前使用Json.net将数据序列化为json.

我们正在经历间歇性的内存使用突然激增,我们怀疑它可能源于json.net在序列化数据时没有识别引用循环(因为实体框架可能正在使用代理类进行一些延迟加载voodoo,这些代码类在json.net的雷达下)

我以为我会限制Json.net被允许用于序列化数据的深度(至少在发生这种情况时我们会得到一个明智的异常,所以我们可以在数据模型中修复它),但我很快就发现了MaxDepth JsonSerializerSettings的属性仅在反序列化对象时启动.

在序列化时是否有任何已知的方法对json.net施加限制?

我无法想到用Json.NET开箱即用的方法,因为(正如你正确观察到的) MaxDepth在序列化时会被忽略.您可以做的是继承 JsonTextWriter并自己进行检查:
  1. public class MaxDepthJsonTextWriter : JsonTextWriter
  2. {
  3. public int? MaxDepth { get; set; }
  4. public int MaxObservedDepth { get; private set; }
  5.  
  6. public MaxDepthJsonTextWriter(TextWriter writer,JsonSerializerSettings settings)
  7. : base(writer)
  8. {
  9. this.MaxDepth = (settings == null ? null : settings.MaxDepth);
  10. this.MaxObservedDepth = 0;
  11. }
  12.  
  13. public MaxDepthJsonTextWriter(TextWriter writer,int? maxDepth)
  14. : base(writer)
  15. {
  16. this.MaxDepth = maxDepth;
  17. }
  18.  
  19. public override void WriteStartArray()
  20. {
  21. base.WriteStartArray();
  22. CheckDepth();
  23. }
  24.  
  25. public override void WriteStartConstructor(string name)
  26. {
  27. base.WriteStartConstructor(name);
  28. CheckDepth();
  29. }
  30.  
  31. public override void WriteStartObject()
  32. {
  33. base.WriteStartObject();
  34. CheckDepth();
  35. }
  36.  
  37. private void CheckDepth()
  38. {
  39. MaxObservedDepth = Math.Max(MaxObservedDepth,Top);
  40. if (Top > MaxDepth)
  41. throw new JsonSerializationException(string.Format("Depth {0} Exceeds MaxDepth {1} at path \"{2}\"",Top,MaxDepth,Path));
  42. }
  43. }

然后,要手动生成JSON字符串,您可以像这样使用它:

  1. var settings = new JsonSerializerSettings { MaxDepth = 10 };
  2. string json;
  3. try
  4. {
  5. using (var writer = new StringWriter())
  6. {
  7. using (var jsonWriter = new MaxDepthJsonTextWriter(writer,settings))
  8. {
  9. JsonSerializer.Create(settings).Serialize(jsonWriter,myClass);
  10. // Log the MaxObservedDepth here,if you want to.
  11. }
  12. json = writer.ToString();
  13. }
  14. Debug.WriteLine(json);
  15. }
  16. catch (Exception ex)
  17. {
  18. Debug.WriteLine(ex);
  19. json = null;
  20. throw;
  21. }

由于您的代码包含web-api,如果您要在Web API调用中执行此操作,则可以按照Rick Strahl的说明为JSON创建自定义MediaTypeFormatter:Using an alternate JSON Serializer in ASP.NET Web API;然后在生成json字符串时在OnWriteToStreamAsync方法中使用上面的代码.

猜你在找的Json相关文章