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

时间:2016-04-15 08:05:11

标签: c# linux mono npgsql

我有这个简单的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();
    }
  }
}

我用mono(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

谢谢

4 个答案:

答案 0 :(得分:14)

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

答案 1 :(得分:0)

我想把这些信息提供给那些会像我一样得到不同异常的人,我有:

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

on

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

答案 2 :(得分:0)

基于@ pikos的回复,我发现了一个nuget包中的一个程序集,我用它来运送它自己的Mono.Security.dll。但是,单声道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。

答案 3 :(得分:0)

正如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。我的~/.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而对Npgsql 2.2.7有依赖性,那么只需使用较新的EntityFramework6.Npgsql程序包,该程序包就对Npgsql> = 4.0.2有依赖性,因此此问题会根本不存在。