如何为NLog.Web的${aspnet-user-identity}实现domain参数功能?
解决${aspnet-user-identity}隐藏Domain的需求
好问题!我之前在项目里也遇到过一模一样的需求——${aspnet-user-identity}默认会输出完整的domain\username格式,但偏偏不像${windows-identity}有现成的domain参数可以控制显示逻辑。这里有几个实用的方案,你可以根据自己的场景选:
方案1:用内置的${replace}布局渲染器快速处理
如果只是偶尔需要去掉Domain,最快捷的方式是用NLog自带的字符串替换功能,结合正则表达式把Domain部分剔除。比如:
${replace:inner=${aspnet-user-identity}:searchFor=^.*\\:replaceWith=}
- 逻辑说明:正则
^.*\\会匹配从字符串开头到最后一个反斜杠的所有内容(包括反斜杠本身),替换成空字符串后,就只剩下纯用户名了。 - 优势:完全不需要写C#代码,直接在NLog配置里就能实现。
- 兼容性:如果用户身份本身没有Domain(比如Forms认证的用户),这个表达式也不会出错,会原样输出用户名。
方案2:自定义布局渲染器(更灵活可控)
如果项目里很多地方都需要这个功能,或者需要更复杂的逻辑(比如根据环境决定是否显示Domain),那自定义一个布局渲染器会更合适。你可以继承NLog.Web自带的AspNetUserIdentityLayoutRenderer,添加一个控制Domain显示的属性:
using NLog.Web.LayoutRenderers; using System.Web; [LayoutRenderer("aspnet-user-identity-with-domain")] public class AspNetUserIdentityWithDomainLayoutRenderer : AspNetUserIdentityLayoutRenderer { // 默认保留Domain,和原渲染器行为保持一致 public bool IncludeDomain { get; set; } = true; protected override void Append(StringBuilder builder, LogEventInfo logEvent) { var identityName = HttpContext.Current?.User?.Identity?.Name; if (string.IsNullOrEmpty(identityName)) { // 如果获取不到身份信息,调用基类的默认逻辑 base.Append(builder, logEvent); return; } if (!IncludeDomain) { var lastBackslashPos = identityName.LastIndexOf('\\'); if (lastBackslashPos >= 0) { // 截取反斜杠后面的部分作为纯用户名 identityName = identityName.Substring(lastBackslashPos + 1); } } builder.Append(identityName); } }
然后在项目启动时注册这个自定义渲染器(比如Global.asax或者Startup类中):
NLog.Config.ConfigurationItemFactory.Default.LayoutRenderers .RegisterDefinition("aspnet-user-identity-with-domain", typeof(AspNetUserIdentityWithDomainLayoutRenderer));
之后就能在NLog配置里灵活使用了:
<!-- 只显示用户名 --> ${aspnet-user-identity-with-domain:IncludeDomain=false} <!-- 显示完整的domain\username(默认行为) --> ${aspnet-user-identity-with-domain}
方案3:ASP.NET Core专属小技巧(如果是Core项目)
如果你的项目是ASP.NET Core,还可以直接通过Claims获取纯用户名(通常NameClaim就是不带Domain的,取决于你的认证配置):
${aspnet-user-claims:ClaimType=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name}
不过这个依赖于你的认证系统是否把纯用户名存在这个Claim里,适用性可能不如前两个方案广。
内容的提问来源于stack exchange,提问作者Amit Ben Ami
相关产品推荐
相关产品推荐

