3

MongoDB.Driver我使用 C#库连接到 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的 s 很好,但是,当我尝试检索数据库中的集合时,我得到一个AggregateException,当我这样做时mongoDb.GetCollectionNamesAsync().Result,异常详细信息是

AggregateException InnerException (count 1) MongoQueryException: QueryFailure flag 为真(响应为 { "$err" : "not authorized for query on taurusEvents.system.namespaces", "code" : 13 })。

我不确定这个异常告诉我什么。客户端的身份验证很好,但我似乎可以查询数据库。我在这里想念什么?


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

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"}]})

谢谢你的时间。

4

2 回答 2

1

GetCollection 和 GetCollectionNamesAsync 是不同的。

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

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

于 2015-02-05T21:27:01.393 回答
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 数据库的权限。

于 2015-02-05T18:53:59.067 回答