.NET 7+IIS环境下NLog数据库日志报错:无法加载Microsoft.Data.SqlClient
问题描述
运行在IIS上的.NET 7项目,配置NLog写入数据库时出现以下报错:
DatabaseTarget(Name=MessageStoredProcedure): Failed to create ConnectionType from DBProvider=Microsoft.Data.SqlClient.SqlConnection,Microsoft.Data.SqlClient Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Data.SqlClient, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
用户当前NLog配置:
<target name="asyncReqResMessage" type="AsyncWrapper"> <target type="Database" name="MessageStoredProcedure"> <keepConnection>true</keepConnection> <dbProvider>Microsoft.Data.SqlClient.SqlConnection,Microsoft.Data.SqlClient</dbProvider> <connectionString>Data Source=****.company.org,1433; Initial Catalog=Logging; User ID=*****; Password=****; Connection Timeout=30; Application Name=test;</connectionString> <commandText>EXEC logInsertExternalRequest @EndPoint, @Method, @LogKey, @Server, @TokenId, @ReceivedDate, @RequestType, @RequestIP, @RequestHeaders, @RequestMessage, @ResponseDate, @ResponseHeaders, @ResponseMessage, @ResponseCode, @ResponseId, @Duration</commandText> <parameter name="@EndPoint" layout="${event-properties:logInfo:objectpath=EndPoint}" /> <parameter name="@Method" layout="${event-properties:logInfo:objectpath=Method}" /> <parameter name="@LogKey" layout="${event-properties:logInfo:objectpath=LogKey}" /> <parameter name="@Server" layout="${machinename}" /> <parameter name="@TokenId" layout="${event-properties:logInfo:objectpath=TokenId}" /> <parameter name="@ReceivedDate" layout="${event-properties:logInfo:objectpath=ReceivedDate}" /> <parameter name="@RequestIP" layout="${event-properties:logInfo:objectpath=RequestIP}" /> <parameter name="@RequestType" layout="${event-properties:logInfo:objectpath=RequestType}" /> <parameter name="@RequestHeaders" layout="${event-properties:logInfo:objectpath=RequestHeaders}" /> <parameter name="@RequestMessage" layout="${event-properties:logInfo:objectpath=RequestMessage}" /> <parameter name="@ResponseDate" layout="${event-properties:logInfo:objectpath=ResponseDate}" /> <parameter name="@ResponseHeaders" layout="${event-properties:logInfo:objectpath=ResponseHeaders}" /> <parameter name="@ResponseMessage" layout="${event-properties:logInfo:objectpath=ResponseMessage}" /> <parameter name="@ResponseCode" layout="${event-properties:logInfo:objectpath=ResponseCode}" /> <parameter name="@ResponseId" layout="${event-properties:logInfo:objectpath=ResponseId}" /> <parameter name="@Duration" layout="${event-properties:logInfo:objectpath=Duration}" /> </target> </target>
已确认bin目录存在Microsoft.Data.SqlClient.dll,且dbProvider配置已更新,以下是解决办法:
指定完整的程序集标识
Microsoft.Data.SqlClient的公钥令牌为23ec7fc2d6eaa4a5,在dbProvider中补充版本号和公钥令牌,确保NLog能精确定位程序集:<dbProvider>Microsoft.Data.SqlClient.SqlConnection,Microsoft.Data.SqlClient, Version=5.1.0.0, Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5</dbProvider>版本号可从bin目录下
Microsoft.Data.SqlClient.dll的属性→详细信息中查看,替换为实际安装的版本。使用NLog内置的数据库提供程序别名
直接用NLog内置的别名替代完整类名,避免手动配置错误:<dbProvider>Microsoft.Data.SqlClient</dbProvider>NLog会自动映射到正确的连接类型,无需手动指定程序集信息。
检查IIS应用程序池配置
打开IIS管理器,找到项目对应的应用程序池,右键→高级设置:- 将“.NET CLR版本”设置为
No Managed Code(.NET 7为独立部署,不需要IIS托管CLR) - 确认应用程序池的“启用32位应用程序”设置与项目平台一致(若项目为64位则关闭该选项)
- 将“.NET CLR版本”设置为
验证NuGet包复制属性
在项目中找到Microsoft.Data.SqlClient引用,右键→属性:- 确保“复制到输出目录”设置为“始终复制”或“如果较新则复制”,防止部署时程序集未正确复制到bin目录
添加程序集绑定重定向(若需)
在web.config中添加绑定重定向,确保加载正确版本的程序集:<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Microsoft.Data.SqlClient" publicKeyToken="23ec7fc2d6eaa4a5" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>替换版本号为实际安装的
Microsoft.Data.SqlClient版本。
内容的提问来源于stack exchange,提问作者george

