C#执行MongoDB db.getUser原生命令返回空users数组问题
问题成因
- 核心错误是
usersInfo命令的执行上下文不符合MongoDB的规则:当传入{user: <用户名>, db: <数据库名>}格式的参数查询用户时,跨库查询请求必须在admin数据库实例上执行。如果在普通业务库的IMongoDatabase实例上运行该命令,MongoDB不会抛出语法或权限错误,会直接返回ok=1、users为空数组的结果,和你遇到的现象完全一致。 - 方法定义缺陷:当前方法返回值为非泛型
Task,即使命令成功返回结果,也无法将用户信息传递给调用方。 - 冗余代码:现有
try-catch块仅做无意义的异常重抛,没有附加任何错误处理逻辑,完全可以移除。
修正方案
根据实际查询场景二选一即可:
场景1:需要支持查询任意数据库下的用户
从现有数据库实例拿到MongoClient,先获取admin库实例,再在admin库上执行命令,同时修正返回值:
using MongoDB.Bson; using MongoDB.Driver; public static async Task<BsonDocument> GetUserInfoAsync(this IMongoDatabase database, string username, string userDbName) { // 跨库查询用户必须在admin库执行命令 IMongoDatabase adminDb = database.Client.GetDatabase("admin"); BsonDocument commandDoc = new BsonDocument { {"usersInfo", new BsonDocument { { "user", username }, { "db", userDbName } } } }; BsonDocumentCommand<BsonDocument> command = new BsonDocumentCommand<BsonDocument>(commandDoc); BsonDocument result = await adminDb.RunCommandAsync(command); // 提取第一条用户记录,用户不存在时返回null return result["users"].AsBsonArray.FirstOrDefault()?.AsBsonDocument; }
场景2:仅需要查询当前数据库实例下的用户
可以简化命令参数,直接在当前绑定的数据库实例上执行,不需要传入额外的数据库名,也不需要走admin库:
using MongoDB.Bson; using MongoDB.Driver; public static async Task<BsonDocument> GetUserInfoAsync(this IMongoDatabase database, string username) { BsonDocument commandDoc = new BsonDocument("usersInfo", username); BsonDocumentCommand<BsonDocument> command = new BsonDocumentCommand<BsonDocument>(commandDoc); BsonDocument result = await database.RunCommandAsync(command); return result["users"].AsBsonArray.FirstOrDefault()?.AsBsonDocument; }
注意:执行命令使用的数据库账号,需要拥有目标用户所属数据库的viewUser权限,否则会出现权限报错,或无报错返回空结果的情况。
内容的提问来源于stack exchange,提问作者user19510842
相关产品推荐
相关产品推荐

