使用dotnetcore连接到mongo db

时间:2016-08-04 16:11:04

标签: mongodb .net-core

我正在测试新的MongoDB.Driver的测试版,因为c#与dotnet core兼容,我无法使连接正常工作。我在端口27017下的docker容器上运行了mongo server v3.3,我可以通过docker exec -it和GUI(Robomongo)通过控制台成功访问。

我在我的project.json中使用"MongoDB.Driver": "2.3.0-beta1",我运行的代码如下:

public class Program
{
    public static void Main(string[] args)
    {
        var client = new MongoClient("mongodb://localhost:27017");

        var db = client.GetDatabase("newdatabase");

        var collection = db.GetCollection<Person>("mycollection");

        collection.InsertOne(new Person{Id = "1", Age = 32});
    }

    public class Person
    {
        public string Id{ get; set;}
        public int Age{ get; set;}
    }
}

我得到的例外是:

A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = WritableServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "Automatic", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", EndPoint: "Unspecified/localhost:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.PlatformNotSupportedException: This platform does not support connecting sockets to DNS endpoints via the instance Connect and ConnectAsync methods, due to the potential for a host name to map to multiple IP addresses and sockets becoming invalid for use after a failed connect attempt. Use the static ConnectAsync method, or provide to the instance methods the specific IPAddress desired.
   at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
   at System.Net.Sockets.Socket.Connect(String host, Int32 port)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MongoDB.Driver.Core.Connections.TcpStreamFactory.<ConnectAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MongoDB.Driver.Core.Connections.TcpStreamFactory.<CreateStreamAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
   --- End of inner exception stack trace ---
   at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MongoDB.Driver.Core.Servers.ServerMonitor.<HeartbeatAsync>d__27.MoveNext()" }] }.

是否有明显缺失或错误配置的东西,或者是否使用此驱动程序的早期阶段?

2 个答案:

答案 0 :(得分:3)

实际上如果我将localhost更改为127.0.0.1就可以了。出于某种原因,它不喜欢这个名字(注意我使用Docker版本1.12.0-beta21(版本:11019) 5a44e81a0513f32f5c49f7d2966570893451f32f如果有任何帮助的话。)

答案 1 :(得分:1)

在Windows上的Docker-Desktop托管的Kubernetes集群中运行dotnet核心应用程序时遇到相同的问题。我尝试过基于Debian和Alpine的图像,但没有运气。 同样,这似乎也不是Docker问题,因为来自Pod的任何nslookup hostname都会解析正确的IP地址。

我发现的唯一解决方法是在初始化Mongo连接之前将主机名解析为IP地址,因此我最终得到了实用程序方法:

private string GetMongoConnectionStringWithIps(string connectionString) {
    var builder = new MongoUrlBuilder(connectionString);
    var servers = new List<MongoServerAddress>();
    foreach (var server in builder.Servers)
    {
        var address = Dns.GetHostAddresses(server.Host).FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
        servers.Add(new MongoServerAddress(address.ToString(), server.Port));
    }
    builder.Servers = servers;
    return builder.ToMongoUrl().ToString();
}