MongoDb.Driver IMongoDatabase.GetCollectionNamesAsync()异常

时间:2015-02-05 17:44:17

标签: c# mongodb mongodb-query mongodb.driver

我使用C#MongoDB.Driver库连接到MongoDB。一些有效的代码

MongoClient client = MongoClientBuilder.Build(
    "77.199.99.90", 27016, "admin", "pwd");
IReadOnlyList<string> dbNames = this.client.GetDatabaseNamesAsync().Result;
foreach (var dbn in dbNames)
{
    IMongoDatabase mongoDb = client.GetDatabase(dbn);
    var cNames = mongoDb.GetCollectionNamesAsync().Result; <- THIS THROWS AggregateException.
    foreach (var cn in cNames)
    {
        ...
    }
}

所以凭据是正确的,我得到IMongoDatabase就好了,但是,当我尝试检索数据库中的集合时,当我AggregateException时,我得到mongoDb.GetCollectionNamesAsync().Result ,例外细节是

  

AggregateException     InnerException(计数1)     MongoQueryException:         QueryFailure标志为true(响应为{&#34; $ err&#34;:&#34;未授权查询taurusEvents.system.namespaces&#34;,&#34; code&#34;:13}。) / p>

我不确定这个例外是什么告诉我的。客户端上的身份验证很好,但我似乎可以查询数据库。我在这里缺少什么?


编辑。我现在意识到我需要使用凭证来执行此操作,但是,执行

public static MongoClient Build(string host, int port,
    string username, string password, string authDb)
{
    MongoCredential cred = MongoCredential.CreateMongoCRCredential(authDb, username, password);
    MongoClientSettings settings = new MongoClientSettings()
    {
        Credentials = new[] { cred }, 
        Server = new MongoServerAddress(host, port)
    };
    return new MongoClient(settings);
}

我现在提供的身份验证数据库名称authDb也会抛出相同的内部异常。


编辑#2。我发现如果我做

var o = database.GetCollection<BsonDocument>("events");

明确引用集合名称,它可以工作,我得到我的集合。但是我想要一个可用的集合列表,为什么GetCollectionNamesAsync()不起作用?


编辑#3。我使用以下方法创建服务器角色:

1。创建管理员用户:

use admin
db.createUser({user: "admin", pwd: "*******", roles: [{role: "userAdminAnyDatabase", db: "admin"}]})

2。创建其他用户,例如:

use admin
db.createUser({user: "mel", pwd: "*******", roles: [{role: "readWrite", db: "taurusEvents"}, {role: "readWrite", db: "taurusOdds"}, {role: "readWrite", db: "taurusState"}]})

感谢您的时间。

2 个答案:

答案 0 :(得分:1)

由于.Result在.NET中的工作方式,你得到一个AggregateException。

var result = task.Result; // throws an AggregateException if the task faulted

要使代码抛出内部异常,请使用:

var result = task.GetAwaiter().GetResult(); // throws the inner exception if the task faulted
var result = await task; // also throws the inner exception if the task faulted

我怀疑您获得此异常的原因是,当您使用有效凭据时(如果不是,您将很快失败),您正在进行身份验证的用户无权读取taurusEvents数据库。

答案 1 :(得分:1)

GetCollection和GetCollectionNamesAsync是不同的。

GetCollection仅创建表示集合的客户端对象。它实际上并不与服务器通信(因此身份验证永远不会成为问题)。

GetCollectionNamesAsync与服务器通信以获取给定数据库的所有集合的名称。这要求您通过身份验证的用户名至少具有该数据库的读取权限。