And*_*sen 7 lazy-loading json.net asp.net-web-api
我们将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));
}
}
Run Code Online (Sandbox Code Playgroud)
然后,要手动生成 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);
throw;
}
Run Code Online (Sandbox Code Playgroud)
演示小提琴在这里。
由于您的标签包含web-api,如果您想在 Web API 调用中进行此检查,您可以按照 Rick Strahl 的说明MediaTypeFormatter为 JSON创建自定义:在 ASP.NET Web API 中使用备用 JSON 序列化程序;然后OnWriteToStreamAsync在生成json字符串时在方法中使用上面的代码。
| 归档时间: |
|
| 查看次数: |
4052 次 |
| 最近记录: |