使用Serilog Enricher增强日志时访问Session报错:Session未配置
问题原因与解决方案
问题原因
- 中间件顺序错误:
UseSession被放在了UseAuthorization之后,导致部分请求阶段(如授权流程)或Action执行前,Session还未完成初始化。此时Enricher访问context.Session会触发异常——控制器里能正常访问Session,是因为Action执行在UseSession之后,但Enricher可能在更早的阶段被触发(比如授权过程中产生的日志)。 - 直接访问Session属性的风险:
context.Session属性在Session未初始化时会直接抛出异常,而非返回null,这导致即使拿到HttpContext,也无法安全判断Session是否可用。
解决方案
方案一:修正中间件顺序
将UseSession移到UseAuthorization之前,确保Session在所有需要访问它的组件前完成初始化:
var app = builder.Build(); // ... 其他环境配置 ... app.UseRouting(); app.UseSession(); // 调整到此处,位于UseAuthorization之前 app.UseAuthorization(); // ... 路由映射配置 ...
方案二:安全访问Session(避免异常)
修改Enricher代码,通过检查ISessionFeature判断Session是否已初始化,替代直接访问context.Session的方式,避免未初始化时抛出异常:
using Microsoft.AspNetCore.Http.Features; public class HttpContextEnricher(IHttpContextAccessor httpContextAccessor) : ILogEventEnricher { private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor; public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { try { var context = _httpContextAccessor.HttpContext; if (context is null) { return; } // 先获取SessionFeature,判断Session是否已初始化 var sessionFeature = context.Features.Get<ISessionFeature>(); var session = sessionFeature?.Session; if (session == null) { return; } var test = session.GetString("test"); // 将Session中的值添加为日志属性(可选) logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("SessionTest", test ?? "未设置")); } catch (Exception ex) { Console.WriteLine($"Enricher访问Session出错: {ex.Message}"); } } }
补充说明
- 即使修正了中间件顺序,仍可能存在部分日志事件(如应用启动日志、路由匹配前的日志)在Session初始化前触发,因此方案二的安全访问逻辑能有效避免不必要的异常。
- 无需额外使用中间件传递Session信息,通过上述修改即可在Enricher中安全访问Session。
内容的提问来源于stack exchange,提问作者Kyle Fuller
相关产品推荐
相关产品推荐

