2015-02-05 97 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