将Mongodb的Bson类型转换成Json

10

我正在使用Postman测试我的asp.net core 2.2 Web API。我手动编写了JSON,像这样(httppatch):

{
    "query": "{\"name\": \"foo\"}",

    "update": [ "{\"$set\":{\"name\":\"foo2\"}}","{\"$set\":{\"path\": \"foo2 path\"}}" ]
}

现在我在思考如何在客户端构建补丁体。
我的问题是,如何获取与此代码等价的JSON以使其看起来像我手动编写的那样?

var query = Builders<T>.Filter.Eq(e => e.name, "foo");
var updates = Builders<T>.Update.Set(e => e.name, "foo2").Set(e => e.Path, "foo2 path");

我猜这都是关于序列化的问题,你有什么想法怎样才能做到?

--更新--

我找到了这个:

var serializerRegistry = BsonSerializer.SerializerRegistry;
var documentSerializer = serializerRegistry.GetSerializer<T>();
var upList = updates.Render(documentSerializer, serializerRegistry);

但它只抓取最后一组它将所有组合成一个(我的错误,感谢@Simon Mourier指出我的错误!


Builders<T>.Update.Set(e => e.name, "foo2").Set(e => e.Path, "foo2 path").ToJson() 这个你试过了吗? - Black Hole
我尝试了一下,得到了这个结果: '“{ \”_t\“ : \”CombinedUpdateDefinition`1\” }”'。 - Sinan
@PeteGarafano 我进行了一些验证,从FindOneAndUpdateOptions中将BypassDocumentValidation设置为false,并在此之前对update数组中的每个字符串执行BsonDocument.Parse(update[i])以验证字符串。我想这不是完整的验证...你觉得呢? - Sinan
1
你评论中的代码是正确的。它不仅仅获取了最后一个集合,而是将两个集合合并成了这个:{ "$set" : { "name" : "foo2", "path" : "foo2 path" } } 这是预期的结果。 - Simon Mourier
1
你已经有了一个完整的解决方案,Render是将输出转换为Bson/Json等格式的方法。它存在于所有使用C#构建的结构中。你还需要什么? - Simon Mourier
显示剩余3条评论
2个回答

3

这是解决方案:

在客户端

        // serializer
        var serializerRegistry = BsonSerializer.SerializerRegistry;
        var documentSerializer = serializerRegistry.GetSerializer<T>();

        // filter and update
        var filter = Builders<T>.Filter.Eq(e => e.Level, 2);
        var updates = Builders<T>.Update
                     .Set(e => e.Name, "foo2")
                     .Set(e => e.Path, "foo2 path")
                     .Inc(e => e.Level, 1);

        // get the string of the filter and the update
        var filterString = filter.Render(documentSerializer, serializerRegistry);
        var updateString = updates.Render(documentSerializer, serializerRegistry);

        // instantiate patch object with properties to json
        Patch patch = new Patch()
        {
            Query = filterString.ToJson(),
            Update = updateString.ToJson()
        };

        // patch object to json
        var patchJson = patch.ToJson();

在服务器端

    [HttpPatch]
    public async Task<IActionResult> PatchOne([FromBody]Patch patch)
    {
        // don't need to ModelState.isValid, it's done on binding
        
        try
        {
            var update = BsonDocument.Parse(patch.Update);
            var filter = BsonDocument.Parse(patch.Query);

            var result = await _serviceBase.UpdateOneAsync(filter, update);
            
            ...

        }
        catch (System.Exception ex)
        {

            return StatusCode(StatusCodes.Status500InternalServerError, ex.Message.ToJson());
        }
    }

全局模态框(我的解决方案结构)

public class Patch
{
    [Required]
    public string Query { get; set; }
    [Required]
    public string Update { get; set; }
}

感谢您的帮助!!

0

我找到了一种查看查询的方法

你需要创建查询并将其保存在变量中

var query = Builders<T>.Filter.Eq(e => e.name, "foo");
var makeQuery = _collection.Find(query).ToString();

makeQuery 的值为 Filter.Eq


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接