加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

json.net在序列化时限制maxdepth

发布时间:2020-12-16 19:32:30 所属栏目:百科 来源:网络整理
导读:我们将Asp.Net WebAPI与实体框架(延迟加载)一起使用,并在将数据返回给客户端之前使用Json.net将数据序列化为json. 我们正在经历间歇性的内存使用突然激增,我们怀疑它可能源于json.net在序列化数据时没有识别引用循环(因为实体框架可能正在使用代理类进行一些
我们将Asp.Net WebAPI与实体框架(延迟加载)一起使用,并在将数据返回给客户端之前使用Json.net将数据序列化为json.

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

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

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

我无法想到用Json.NET开箱即用的方法,因为(正如你正确观察到的) MaxDepth在序列化时会被忽略.您可以做的是继承 JsonTextWriter并自己进行检查:
public class MaxDepthJsonTextWriter : JsonTextWriter
{
    public int? MaxDepth { get; set; }
    public int MaxObservedDepth { get; private set; }

    public MaxDepthJsonTextWriter(TextWriter writer,JsonSerializerSettings settings)
        : base(writer)
    {
        this.MaxDepth = (settings == null ? null : settings.MaxDepth);
        this.MaxObservedDepth = 0;
    }

    public MaxDepthJsonTextWriter(TextWriter writer,int? maxDepth)
        : base(writer)
    {
        this.MaxDepth = maxDepth;
    }

    public override void WriteStartArray()
    {
        base.WriteStartArray();
        CheckDepth();
    }

    public override void WriteStartConstructor(string name)
    {
        base.WriteStartConstructor(name);
        CheckDepth();
    }

    public override void WriteStartObject()
    {
        base.WriteStartObject();
        CheckDepth();
    }

    private void CheckDepth()
    {
        MaxObservedDepth = Math.Max(MaxObservedDepth,Top);
        if (Top > MaxDepth)
            throw new JsonSerializationException(string.Format("Depth {0} Exceeds MaxDepth {1} at path "{2}"",Top,MaxDepth,Path));
    }
}

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

var settings = new JsonSerializerSettings { MaxDepth = 10 };
        string json;
        try
        {
            using (var writer = new StringWriter())
            {
                using (var jsonWriter = new MaxDepthJsonTextWriter(writer,settings))
                {
                    JsonSerializer.Create(settings).Serialize(jsonWriter,myClass);
                    // Log the MaxObservedDepth here,if you want to.
                }
                json = writer.ToString();
            }
            Debug.WriteLine(json);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
            json = null;
            throw;
        }

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读