问题描述
如何编写通用的ASP.NET Core ApiController来从Angular / React等客户端框架进行MongoDB CRUD操作。
注意:Firebase为Firestore和数据库提供了此类客户端库
解决方法
您可以创建一个请求有效负载定义,该定义将包含对象(或集合)名称,操作(Insert
,Replace
,Delete
或您要支持的其他任何对象)和对象本身。将mongo数据库对象注入控制器,按名称获取集合并应用操作。伪代码可能看起来像这样:
class Operation
{
OperationType Type {get; set;}
JObject Object {get; set;}
string ObjectId {get; set;}
string ObjectName {get; set;}
}
[HttpPost]
public async Task<IActionResult> Apply(Operation operation)
{
WriteModel<BsonDocument> model = null;
switch (operation.Type)
{
case OperationType.Insert:
model = new InsertOneModel(ConvertToBsonDocument(operation.Object));
break;
case OperationType.Replace:
model = new ReplaceOneModel(operation.ObjectId,ConvertToBsonDocument(operation.Object));
break;
case OperationType.Delete:
model = new DeleteOneModel(operation.ObjectId);
break;
}
await mongoDatabase.GetCollection<BsonDocument>(operation.ObjectName).BultWriteAsync(new[] {model});
return Ok();
}
或者,为了使操作与http规范保持一致并实现更好的分离,您可以将逻辑划分为多个动作:
[HttpGet("{name}/{objectId}")]
public async Task<IActionResult> Get(string name,string objectId)
{
var document = await mongoDatabase.GetCollection<BsonDocument>(name).Find(new BsonDocument("_id",ObjectId.Parse(objectId))).FirstOrDefaultAsync();
var dotNetObj = BsonTypeMapper.MapToDotNetValue(document);
var json = JsonConvert.SerializeObject(dotNetObj);
return document is null
? NotFound()
: (IActionResult)Content(json,"application/json");
}
[HttpPost("{name}")]
public async Task<IActionResult> Post(string name,JsonElement @object)
{
await mongoDatabase.GetCollection<BsonDocument>(name).InsertOneAsync(ConvertToBsonDocument(operation.Object));
return Ok();
}
[HttpPut("{name}/{objectId}")]
public async Task<IActionResult> Put(string name,string objectId,JsonElement @object)
{
await mongoDatabase.GetCollection<BsonDocument>(name).ReplaceOneAsync(new BsonDocument("_id",ObjectId.Parse(objectId),ConvertToBsonDocument(operation.Object));
return Ok();
}
[HttpDelete("{name}/{objectId}")]
public async Task<IActionResult> Delete(string name,string objectId)
{
await mongoDatabase.GetCollection<BsonDocument>(name).DeleteOneAsync(new BsonDocument("_id",ObjectId.Parse(objectId));
return Ok();
}