如何在运行时更改 NLog 目标的连接字符串?
How to change NLog target's connection string at runtime?
在我的 WebAPI 应用程序中,我试图根据我的自定义 header 值登录到 Application_BeginRequest
中的几个单独的数据库。
为此,我尝试修改 Nlog.config
中的 target
,如下所示:
<target name="database"
xsi:type="Database"
connectionString="${gdc:item=myConnectionstring}"
commandText="..sql command..">..params..</target>
并且在 Application_BeginRequest
中,我尝试像这样设置 myConnectionstring
:
GlobalDiagnosticsContext.Set("myConnectionString", connectionString);
但这不起作用,在 NLog 的 internalLogFile
错误中显示:
2015-02-19 12:12:48.8776 Error Error when writing to database System.InvalidOperationException: The ConnectionString property has not been initialized.
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString)
at NLog.Targets.DatabaseTarget.WriteEventToDatabase(LogEventInfo logEvent)
at NLog.Targets.DatabaseTarget.Write(LogEventInfo logEvent)
我尝试将以下参数写入数据库(使用常量连接字符串配置):
<parameter name="@cn" layout="${gdc:myConnectionstring}"/>
<parameter name="@cn1" layout="${gdc:item=myConnectionstring}"/>
但它们似乎是空的,但是当我调试我的 WebApi 操作时抛出我希望写入数据库的错误,GlobalDiagnosticsContext.Get("myConnectionString")
returns 预期值。
我做错了什么?为什么我可以在 GlobalDiagnosticsContext.Get("myConnectionString")
中看到预期值,但 ${gdc:item=myConnectionstring}
解析为空字符串?
找到了实现该目标的替代方法:
var databaseTarget = (DatabaseTarget)LogManager.Configuration.FindTargetByName("database");
databaseTarget.ConnectionString = connectionString;
LogManager.ReconfigExistingLoggers();
但是仍然不清楚为什么 GlobalDiagnosticsContext
东西不工作..
感谢解答!
不过,如果您想使用异步数据库目标,则需要先获取包装目标:
DatabaseTarget databaseTarget;
var target = LogManager.Configuration.FindTargetByName("database");
if (target is AsyncTargetWrapper)
databaseTarget = (target as AsyncTargetWrapper).WrappedTarget as DatabaseTarget;
else
databaseTarget = target as DatabaseTarget;
if (databaseTarget == null)
throw new NullReferenceException("Can't find DatabaseTarget with name 'database'");
databaseTarget.ConnectionString = connectionStringSelected.ConnectionString;
LogManager.ReconfigExistingLoggers();
在我的 WebAPI 应用程序中,我试图根据我的自定义 header 值登录到 Application_BeginRequest
中的几个单独的数据库。
为此,我尝试修改 Nlog.config
中的 target
,如下所示:
<target name="database"
xsi:type="Database"
connectionString="${gdc:item=myConnectionstring}"
commandText="..sql command..">..params..</target>
并且在 Application_BeginRequest
中,我尝试像这样设置 myConnectionstring
:
GlobalDiagnosticsContext.Set("myConnectionString", connectionString);
但这不起作用,在 NLog 的 internalLogFile
错误中显示:
2015-02-19 12:12:48.8776 Error Error when writing to database System.InvalidOperationException: The ConnectionString property has not been initialized.
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString)
at NLog.Targets.DatabaseTarget.WriteEventToDatabase(LogEventInfo logEvent)
at NLog.Targets.DatabaseTarget.Write(LogEventInfo logEvent)
我尝试将以下参数写入数据库(使用常量连接字符串配置):
<parameter name="@cn" layout="${gdc:myConnectionstring}"/>
<parameter name="@cn1" layout="${gdc:item=myConnectionstring}"/>
但它们似乎是空的,但是当我调试我的 WebApi 操作时抛出我希望写入数据库的错误,GlobalDiagnosticsContext.Get("myConnectionString")
returns 预期值。
我做错了什么?为什么我可以在 GlobalDiagnosticsContext.Get("myConnectionString")
中看到预期值,但 ${gdc:item=myConnectionstring}
解析为空字符串?
找到了实现该目标的替代方法:
var databaseTarget = (DatabaseTarget)LogManager.Configuration.FindTargetByName("database");
databaseTarget.ConnectionString = connectionString;
LogManager.ReconfigExistingLoggers();
但是仍然不清楚为什么 GlobalDiagnosticsContext
东西不工作..
感谢解答!
不过,如果您想使用异步数据库目标,则需要先获取包装目标:
DatabaseTarget databaseTarget;
var target = LogManager.Configuration.FindTargetByName("database");
if (target is AsyncTargetWrapper)
databaseTarget = (target as AsyncTargetWrapper).WrappedTarget as DatabaseTarget;
else
databaseTarget = target as DatabaseTarget;
if (databaseTarget == null)
throw new NullReferenceException("Can't find DatabaseTarget with name 'database'");
databaseTarget.ConnectionString = connectionStringSelected.ConnectionString;
LogManager.ReconfigExistingLoggers();