NLog FindTargetByName返回Null问题求助(VB.NET 4.5+VS2013)
我之前在使用NLog 4.x的时候也碰到过类似的情况,结合你描述的场景(能通过AllTargets拿到目标但按名称查找失败),给你几个具体的排查和解决方向:
1. 先确认目标名称的大小写一致性
NLog的FindTargetByName方法是大小写敏感的!你检查下配置文件里MailTarget的name属性是不是和你代码里写的"Email_Target"完全一致?比如有没有不小心写成了"email_target"或者"Email-Target"?
因为AllTargets是枚举所有加载的目标,不管名称拼写细节,而按名称查找时大小写不匹配就会直接返回null,这是最容易踩的坑。
2. 检查目标是否被包装器嵌套
如果你的MailTarget被包装在AsyncTargetWrapper或者其他包装目标里(比如BufferingTargetWrapper),那么FindTargetByName("Email_Target")找到的会是顶层的包装器目标,而不是内部的MailTarget,直接转换类型自然会失败。
比如你的配置可能是这样的:
<targets> <target name="Email_Target" type="AsyncWrapper"> <target type="Mail" name="InnerMailTarget" to="original@example.com" ... /> </target> </targets>
这种情况下,AllTargets会同时列出AsyncTargetWrapper(名称Email_Target)和内部的MailTarget(名称InnerMailTarget)。你需要先拿到包装器,再获取它的内部目标:
Dim currentConfig = LogManager.Configuration Dim topLevelTarget = currentConfig.FindTargetByName("Email_Target") ' 尝试转换为AsyncWrapper Dim asyncWrapper = TryCast(topLevelTarget, Targets.Wrappers.AsyncTargetWrapper) If asyncWrapper IsNot Nothing Then Dim mailTarget = TryCast(asyncWrapper.WrappedTarget, Targets.MailTarget) If mailTarget IsNot Nothing Then ' 这里可以修改邮件目标的属性了 mailTarget.To = "new-recipient@example.com" mailTarget.SmtpServer = "your-smtp-server.com" ' 别忘了将修改后的配置重新赋值给LogManager,让NLog生效 LogManager.Configuration = currentConfig End If End If
3. 确保配置已经完全加载
如果你是在应用启动的早期(比如Application_Start之前)调用FindTargetByName,可能NLog还没完成配置的加载。可以手动触发配置加载:
' 确保配置已加载 LogManager.LoadConfiguration() Dim currentConfig = LogManager.Configuration Dim mailTarget = currentConfig.FindTargetByName(Of Targets.MailTarget)("Email_Target")
4. 确认操作的是当前活跃的配置实例
如果你之前手动修改过配置并重新赋值给LogManager.Configuration,要确保你是从LogManager.Configuration获取最新的配置实例,而不是使用之前缓存的旧实例。
最后提醒
不管哪种情况,当你修改完MailTarget的属性后,一定要把修改后的配置重新赋值给LogManager.Configuration,这样NLog才会应用你的更改。
内容的提问来源于stack exchange,提问作者SteveCinq

