MongoDb.Driver IMongoDatabase.GetCollectionNamesAsync() Исключение

Я подключаюсь к MongoDB, используя C# MongoDB.Driver библиотека. Какой-то код, который работает

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 (count 1) MongoQueryException: флаг QueryFailure был истинным (ответ был { "$err": "не авторизован для запроса на 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() не работает?


Edit # 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 ответа

Вы получаете 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.

GetCollection и GetCollectionNamesAsync различаются.

GetCollection просто создает объект на стороне клиента, который представляет коллекцию. На самом деле он не общается с сервером (поэтому проверка подлинности никогда не будет проблемой).

GetCollectionNamesAsync обращается к серверу, чтобы получить имена всех коллекций для данной базы данных. Для этого необходимо, чтобы имя пользователя, с которым вы прошли аутентификацию, имело как минимум разрешение на чтение в этой базе данных.

Другие вопросы по тегам