2015-02-05 99 views
3

我使用C#MongoDB.Driver库连接到MongoDB。该工程MongoDb.Driver IMongoDatabase.GetCollectionNamesAsync()异常

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标志是真实的(反应是{ “$ ERR”: “未授权对taurusEvents.system.namespaces查询”, “密码”: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"}]}) 

感谢您的时间。

回答

1

因为这种方式,你正在得到一个AggregateException.Result在.NET中有效。

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数据库。

+0

嗨,罗伯特,谢谢。我明白为什么我得到一个'AggregateException'而不是另一个类型,我不明白为什么我得到'MongoQueryException'。我想我可能需要指定认证数据库... – MoonKnight 2015-02-05 18:58:07

+0

拥有有效的用户名和密码是不够的。用户名还必须具有使用您正在尝试使用的任何数据库的权限。 在这种情况下,您用来验证身份的用户名无权访问taurusEvents数据库。 查看授权文档: http://docs.mongodb.org/manual/core/authorization/ – 2015-02-05 21:17:13

+0

谢谢,我会检查权限。唯一令我困惑的是我已经将用户设置为“admin”,以便它拥有所有可用的访问权限。这一定是没有做好,我会再次检查......非常感谢您的时间。 – MoonKnight 2015-02-06 10:09:31

1

GetCollection和GetCollectionNamesAsync是不同的。

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

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

+0

仅供参考:在最新版本(测试版2)中,GetCollectionNamesAsync已被ListCollectionsAsync替换,它返回描述集合的文档的游标(这些文档的“name”元素包含集合的名称)。 – 2015-02-05 21:31:20

+0

我会再看看,再次感谢。我用我用来创建用户的内容编辑了这个问题,你能看到明显的错误吗? – MoonKnight 2015-02-06 11:11:30