无法加载类型 'System.Net.Security.SslStream'

Could not load type 'System.Net.Security.SslStream'

我有这个简单的 C# 程序:

using Npgsql;
public class App {
  public static void Main(string[] args) {
    const string CONNECTION_STRING = "Host=myserver;Username=mylogin;Password=mypass;Database=mydatabase";
    using (var conn = new NpgsqlConnection(CONNECTION_STRING)) {
      conn.Open();
    }
  }
}

我用单声道(mcs)编译它:

mcs -target:exe -lib:bin -r:System.Data.dll -r:Npgsql.dll -r:System.dll -r:Mono.Security.dll -out:bin/ssl.exe src/App.cs

当我执行时,抛出一个错误:

Unhandled Exception:
System.TypeLoadException: Could not load type 'System.Net.Security.SslStream' from assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
  at Npgsql.NpgsqlConnector.Open () <0x4155f7f0 + 0x00115> in <filename unknown>:0 
  at Npgsql.NpgsqlConnectorPool.GetPooledConnector (Npgsql.NpgsqlConnection Connection) <0x4155c8d0 + 0x00a4f> in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeLoadException: Could not load type 'System.Net.Security.SslStream' from assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
  at Npgsql.NpgsqlConnector.Open () <0x4155f7f0 + 0x00115> in <filename unknown>:0 
  at Npgsql.NpgsqlConnectorPool.GetPooledConnector (Npgsql.NpgsqlConnection Connection) <0x4155c8d0 + 0x00a4f> in <filename unknown>:0 

我的Npgsql.dll版本

$ monop2 -r Npgsql.dll 

Assembly Information:
Npgsql
Version=2.2.0.0
Culture=neutral
PublicKeyToken=5d8b90d52f46fda7

我的编译器:

$ mcs --version
Mono C# compiler version 4.4.0.0

$ mono --version
Mono JIT compiler version 4.4.0 (Stable 4.4.0.40/f8474c4 Mon Mar 28 12:22:29 UTC 2016)
Copyright (`u`C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS:           __thread
SIGSEGV:       altstack
Notifications: epoll
Architecture:  amd64
Disabled:      none
Misc:          softdebug 
LLVM:          supported, not enabled.
GC:            sgen

最后,我的环境:

$ uname --all
Linux abe 4.5.0-1-ARCH #1 SMP PREEMPT Tue Mar 15 09:41:03 CET 2016 x86_64 GNU/Linux

谢谢

我有一个问题 - bin 文件夹中是否有库 Mono.Security.dll?如果是,请删除并重试。

我想将此信息提供给像我一样会遇到不同异常的人,我有:

System.TypeLoadException: Failure has occurred while loading a type. at Npgsql.NpgsqlConnector.Open () [0x0002b] in <filename unknown>:0  at Npgsql.NpgsqlConnectorPool.GetPooledConnector (Npgsql.NpgsqlConnection Connection) [0x0017e] in <filename unknown>:0

conn.Open();

但 PIKos 解决方案也适用于我。

我正在使用:

Mono JIT compiler version 4.4.0 (tarball Tue Jun 14 13:41:51 UTC 2016)

Npgsql.dll version 2.1.0.0

根据@pikos 的回复,我发现我正在使用的 nuget 包中的一个程序集是自带的 Mono.Security.dll。然而,mono 4.4.1 moves some of the types out of that assembly,并且可能也会移动一些。因为我没有明确引用 Mono.Security,[x|ms]build 正在通过使用我的 packages 文件夹中的不兼容程序集来解决间接依赖关系。

为了解决这个问题,没有任何其他解决方法(例如,每次构建都删除程序集),我只是添加了一个对系统 Mono.Security 的显式程序集引用。这迫使改用 GAC 中的 4.4.1 版本。由于不使用 nuget 中的那个,我丢失了提示 nuget 的构建者包含他们自己的 Mono.Security 的补丁,但我现在可以接受。 YMMV.

正如 PiKos 指出的那样,罪魁祸首是 Npgsql 2.x NuGet 包嵌入的 Mono.Security.dll。在您的 bin 目录中删除它确实解决了这个问题,但您必须在每次清理和重建解决方案时手动执行此操作。

我没有删除它,而是选择 修复 ~/.nuget/packages/npgsql/2.2.7/lib/net45 中的 Npgsql 2.2.7 包,方法是将 Mono.Security.dll 重命名为 Mono.Security.dll.original 和在 mono 的 GAC 中向 Mono.Security.dll 添加符号 link。这是我的 ~/.nuget/packages/npgsql/2.2.7/lib/net45 目录的样子:

lrwxr-xr-x Mono.Security.dll -> /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gac/Mono.Security/4.0.0.0__0738eb9f132ed756/Mono.Security.dll
-rwxrw-rw- Mono.Security.dll.original
-rwxrw-rw- Npgsql.dll
-rwxrw-rw- Npgsql.xml
drwxr-xr-x de
drwxr-xr-x es
drwxr-xr-x fi
drwxr-xr-x fr
drwxr-xr-x ja
drwxr-xr-x zh-CN

此解决方案的优势在于它适用于所有 引用 Npgsql NuGet 包的项目。

并且如果您因为选择了 Npgsql.EntityFramework, then simply use the more recent EntityFramework6.Npgsql 依赖于 Npgsql >= 4.0.2 的软件包而获得了对 Npgsql 2.2.7 的依赖,那么这个问题根本不存在。