MongoDB C# - 如何将任意JSON文档保存为动态类型?

Tur*_*urp 8 mongodb-.net-driver

我正在尝试编写一个通用的Web Api控制器,它允许我将JSON文档保存到集合中而不指定C#类型.我试图将代码压缩到基本要素:

public class PassThroughController : ApiController
{
    [Route("api/mongodb/{collection}")]
    public void Post(string collection, dynamic document)
    {
        const string connectionString = "mongodb://localhost";

        var client = new MongoClient(connectionString);
        var db = client.GetServer().GetDatabase("SampleDb");
        var mongoCollection = db.GetCollection(collection);

        mongoCollection.Save(document,
            new MongoInsertOptions
            {
                WriteConcern = WriteConcern.Acknowledged
            });
        }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试发布一个简单的文档:

{ id: "2112", name: "Rush" }
Run Code Online (Sandbox Code Playgroud)

但无论我发送给方法的是什么,我都会收到与此类似的错误:"保存只能用于具有Id的文档."

我们尝试了Id(Id,id,_id)的许多不同属性,但它们都会导致类似的问题.

有任何想法吗?

谢谢

Tur*_*urp 13

在同事的帮助下,我想出了一个解决方案:

public class PassThroughController : ApiController
{
    [Route("api/mongodb/{collection}")]
    public void Post(string collection, HttpRequestMessage message)
    {
        const string connectionString = "mongodb://localhost";

        var client = new MongoClient(connectionString);
        var db = client.GetServer().GetDatabase("SampleDb");
        var mongoCollection = db.GetCollection(collection);

        var json = message.Content.ReadAsStringAsync().Result;
        var document = BsonSerializer.Deserialize<BsonDocument>(json);

        mongoCollection.Save(document,
            new MongoInsertOptions
            {
                WriteConcern = WriteConcern.Acknowledged
            });
        }
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*llo 6

我试图保存一些与 ProcessID 关联的动态对象,这个动态对象是完全“动态的”,有时它可以是一个具有一些任意数据和名称的属性,有时它可以是 100 个属性,每个属性的名称完全任意。事实上,它是一个来自 Angular 5 应用程序的对象,它从(惊喜)一些 JSON 对象生成一个动态表单。我的“基”类,即插入 mongo 的类,如下所示:

public class MongoSave {

    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))]
    public string Id { get; set; }        
    public int ProcessID { get; set; }
    public BsonDocument DynamicData { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

在我第一次尝试时,DynamicData属性是 type object,控制器方法接收一切正常,将传入的对象分配给类,但是当将对象保存到 mongo 时,其值DynamicData丢失了。我只得到属性名称。试图BsonSerialize在我的课堂上使用注释但没有成功。

稍微研究了一下,我发现BsonDocument有一个Parse类似于 javascript的方法可以解析包含对象描述的字符串,所以......我将这样的对象发布到我的控制器:

{
    "ProcessID": 987,
    "DynamicData": {
        "name": "Daniel",
        "lastName": "Díaz",
        "employeeID": 654
    }
{
Run Code Online (Sandbox Code Playgroud)

这里有几件事,我通过 Insomnia(邮递员替代品)将此 JSON 发送到 API。在现实世界中,我将通过 Angular 发送这个对象,所以我必须确保申请JSON.stringify(obj)以确保 JSON 对象没问题(不确定 Angular HttpClientpost 对象是作为字符串化的 JSON 还是作为 JS 对象(我''ll test that). 更改我的控制器操作以使用该Parse方法和DynamicDataC# 通用object字符串,如下所示:

[HttpPost("~/api/mongotest/save")]
public async Task<IActionResult> PostObjectToMongo (MongoSaveDTO document) {

    MongoSave mongoItem = new MongoSave() {
        ProcessID = document.ProcessID,
        DynamicData = BsonDocument.Parse(document.DynamicData.ToString())
    };

    await _mongoRepo.AddMongoSave(mongoItem);

    return Ok();
}
Run Code Online (Sandbox Code Playgroud)

MongoSaveDTO它一样MongoSave没有BsonId财产,而不是BsonDocument我使用C#泛型object类型,一切都保存得好好的。