.NET 6 NLog配置:将JSON字符串body转为无转义嵌套JSON
解决NLog日志中JSON字符串转嵌套JSON对象的问题
方法一:代码层面转换(推荐,最可靠)
直接将requestBody字符串反序列化为.NET对象后再传入日志方法,NLog会自动将其序列为嵌套JSON:
使用System.Text.Json(.NET 6内置)
using System.Text.Json; // 反序列化requestBody为动态对象 var bodyObj = JsonSerializer.Deserialize<dynamic>(requestBody); // 日志调用时传入bodyObj而非字符串 _LoggerService.LogEvent(LogLevel.Error, string.Format("Error: {0}, InnerException: {1}, StackTrace: {2}", error.Message, error.InnerException?.Message ?? string.Empty, error.StackTrace), new { host = context.Request.Host, refer = context.Request.Headers.Referer, path = context.Request.Path, method = context.Request.Method, body = bodyObj // 传入反序列化后的对象 }, error);
使用Newtonsoft.Json(若项目已引用)
using Newtonsoft.Json; var bodyObj = JsonConvert.DeserializeObject(requestBody); // 后续日志调用同上,传入bodyObj
方法二:NLog配置层面处理
若不想修改代码,可通过NLog的${json-parse}布局渲染器解析JSON字符串,需确保NLog版本(NLog.Web.AspNetCore/NLog.Extensions.Logging)≥4.7.10。
示例NLog.config配置
<nlog> <targets> <target name="jsonFile" xsi:type="File" fileName="logs/${shortdate}.json"> <layout xsi:type="JsonLayout"> <!-- 基础请求字段 --> <attribute name="host" layout="${event-properties:item=host}" /> <attribute name="refer" layout="${event-properties:item=refer}" /> <attribute name="path" layout="${event-properties:item=path}" /> <attribute name="method" layout="${event-properties:item=method}" /> <!-- 核心:解析body字段的JSON字符串为嵌套对象 --> <attribute name="body" layout="${json-parse:${event-properties:item=body}}" encode="false" /> <!-- 错误相关字段 --> <attribute name="message" layout="${message}" /> <attribute name="stackTrace" layout="${exception:format=StackTrace}" /> </layout> </target> </targets> <rules> <logger name="*" minlevel="Error" writeTo="jsonFile" /> </rules> </nlog>
关键注意点:
- 必须添加
encode="false",否则NLog会再次转义解析后的JSON - 确认
${event-properties:item=body}能正确获取到原始JSON字符串 - 若NLog版本过低,需升级到支持
${json-parse}的版本
常见配置失效原因
- 未添加
encode="false",导致解析后的JSON被二次转义 - NLog版本不支持
${json-parse}渲染器 event-properties的item名称拼写错误(比如写成RequestBody而非body)
内容的提问来源于stack exchange,提问作者FDB
相关产品推荐
相关产品推荐

