如何防止Audit.Net将BodyContent值格式化为转义字符串?
问题根因
Audit.NET 中间件默认将捕获到的请求/响应体作为纯文本字符串存储到审计事件模型的Value字段中,不会自动识别字符串本身是已序列化完成的JSON内容。在生成最终审计日志时,整个事件对象会被整体执行一次序列化,这就导致原本是JSON格式的字符串被当成普通文本再次转义,形成了双重序列化的嵌套字符串结构。这个问题与使用文件日志、SQL Server等存储提供程序无关,属于审计事件捕获阶段的默认行为。
配置调整方法
无需修改存储提供程序的配置,只需要在中间件的捕获逻辑中,对JSON格式的请求/响应体做一次反序列化转换,让捕获到的内容直接以对象结构存在于审计事件模型中。后续整体序列化时,这部分内容就会自动输出为嵌套JSON结构,不再出现转义字符串。
具体修改原有的中间件配置,使用请求/响应体捕获的重载方法增加自定义转换逻辑,仅对JSON类型的内容做反序列化,非JSON格式的内容(如文件流、表单提交)依然保留字符串格式:
app.UseAuditMiddleware(_ => _ .IncludeHeaders() .IncludeResponseHeaders() // 按需为请求体增加相同的JSON反序列化逻辑 .IncludeRequestBody(ctx => { // 仅处理JSON类型的请求内容 if (ctx.Request.ContentType?.Contains("application/json") == true) { return System.Text.Json.JsonSerializer.Deserialize<object>(ctx.Request.BodyAsString); } return ctx.Request.BodyAsString; }) // 响应体捕获的两个参数:第一个是判断是否捕获的条件,第二个是对捕获到的原始内容做转换的委托 .IncludeResponseBody( condition: ctx => ctx.Response.StatusCode == 200, bodyConverter: (rawBody, ctx) => { // 仅处理JSON类型的响应内容 if (ctx.Response.ContentType?.Contains("application/json") == true) { return System.Text.Json.JsonSerializer.Deserialize<object>(rawBody); } return rawBody; });
注意事项
- 上述代码使用
.NET内置的System.Text.Json做反序列化,如果项目统一使用Newtonsoft.Json,只需将反序列化方法替换为Newtonsoft.Json.JsonConvert.DeserializeObject<object>(xxx)即可,不影响最终输出效果。 - 仅修改Audit.NET的全局JSON序列化配置无法解决这个问题:双重序列化的根源是
Value字段存储的是字符串而非对象,全局序列化设置只能控制最终日志的格式,无法自动把字符串内部的JSON结构解析为嵌套对象。 - 反序列化后的对象为动态结构,不需要提前定义强类型的响应DTO,Audit.NET会自动识别其结构并序列化输出,完全匹配预期的嵌套JSON格式。
内容的提问来源于stack exchange,提问作者Ben Wong
相关产品推荐
相关产品推荐

