Serilog - ForContext 将字典值视为复杂对象

Puc*_*acz 5 c# serilog

我正在尝试通过执行以下操作来记录传递给控制器​​的模型:

        _log
            .ForContext("Id", "XXXXXX-XXXX-XXXX-XXXXXXXXX")
            .ForContext("Email", email)
            .ForContext("UserId", userId)
            .ForContext("Parameters", parameters)
            .ForContext("Errors", errors.ToArray())
            .ForContext("ActionArguments", actionArguments)
            .Information(message);
Run Code Online (Sandbox Code Playgroud)

其中actionArguments是 类型IDictionary<string, object> actionArguments。这被解释为

{
   someProperty: "Some.Namespace.Dtos.Something.MyTypeDto"
}
Run Code Online (Sandbox Code Playgroud)

我真的希望someProperty扩展到复杂类型所代表的内容。是否可以?怎么做?

rob*_*ker 7

默认情况下,Serilog 将通过调用获取简单的表示来序列化具有它不理解的类型(包括您自己的自定义类型)的对象ToString()。for 对象的默认实现ToString()仅返回类型的完整名称,这就是 DTO 的类型名称显示在日志上下文中的原因。

你所追求的在 Serilog 中被称为“解构”。在文档中,这被定义为:

解构是获取复杂的 .NET 对象并将其转换为结构的过程,该结构稍后可以表示为 JSON 对象或 XML blob

destructureObjects您可以向方法提供一个可选参数ILogger.ForContext,告诉 Serilog 尝试从对象中提取附加信息:

    .ForContext("ActionArguments", actionArguments, destructureObjects: true)
Run Code Online (Sandbox Code Playgroud)

默认情况下,它将使用反射递归地解构,有效地遍历对象的所有属性以及这些属性的任何属性等,直到找到它知道如何格式化的类型。

请注意,不要使用此方法记录任何敏感信息;Serilog 将尽力包含它发现的每个值。