配置log4net AdoNetAppender连接串Trust Server Certificate参数报错
报错本质是log4net加载的SQL Server客户端和你业务代码使用的客户端版本不匹配,叠加连接字符串关键字格式不符:
- 你当前log4net配置的
connectionType指向.NET Framework内置的旧版System.Data.SqlClient,这个版本的客户端仅识别无空格的连接字符串关键字TrustServerCertificate,无法识别带空格的Trust Server Certificate,因此直接抛出关键字不支持的异常。 - 业务代码中同一段连接字符串能正常连通,是因为你的项目大概率引用了微软独立发布的新版
Microsoft.Data.SqlClientNuGet包,该版本兼容带空格的关键字写法,自然不会报错。 - 将连接字符串挪到app.config再引用无法解决问题,因为问题核心是log4net调用的数据库客户端版本不对,和连接字符串存储位置无关。
任选一种即可解决问题:
方案1:修改连接字符串关键字(最简单,无需调整依赖)
直接把连接字符串里的Trust Server Certificate=True改成无空格的写法,匹配旧版System.Data.SqlClient的关键字规则,参数作用完全一致,都是跳过SQL Server SSL证书链校验,不会影响连接逻辑:
<appender name="DatabaseAppender" type="log4net.Appender.AdoNetAppender"> <bufferSize value="1" /> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <connectionString value="data source=MyServer;initial catalog=MyDataBase;integrated security=false;User ID=MyLogin;Password=MyPassword;TrustServerCertificate=True"/> <!-- 其余原有配置保持不变即可 --> </appender>
方案2:统一log4net和业务代码的数据库客户端
如果你项目本身就是用Microsoft.Data.SqlClient做数据库连接,直接把log4net配置里的connectionType改成对应客户端的类型,让log4net和业务代码用同一个SqlClient版本,就可以兼容你原来写的带空格的关键字:
首先确认项目已经通过NuGet安装了Microsoft.Data.SqlClient包,然后修改配置:
<appender name="DatabaseAppender" type="log4net.Appender.AdoNetAppender"> <bufferSize value="1" /> <!-- 替换为Microsoft.Data.SqlClient的类型定义 --> <connectionType value="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient"/> <connectionString value="data source=MyServer;initial catalog=MyDataBase;integrated security=false;User ID=MyLogin;Password=MyPassword;Trust Server Certificate=True"/> <!-- 其余原有配置保持不变即可 --> </appender>
注意:如果你用的Microsoft.Data.SqlClient版本比较特殊,可以在业务代码中执行typeof(Microsoft.Data.SqlClient.SqlConnection).AssemblyQualifiedName,运行时输出的字符串就是准确的connectionType值,直接复制到配置里即可。配置完成后确认Microsoft.Data.SqlClient.dll已经被复制到程序输出目录,避免出现类型加载失败的问题。
方案3:数据库端配置规避(不推荐)
如果你有数据库服务器的管理权限,可以给SQL Server配置受公共信任的SSL证书,或者关闭服务器端强制加密选项,这样连接时不需要加信任证书参数也能连通,但这种方式会降低数据库连接的传输安全性,非特殊场景不建议使用。
内容的提问来源于stack exchange,提问作者Corabox

