Sinan
Sinan

Reputation: 908

Mongodb Bson type to Json

I am testing my asp.net core 2.2 web api with Postman. I write the JSON manually like this (httppatch):

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

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

Now I am thinking how can I build the patch body on the client side. My question is how can I get the equivalent of this code in json to make it look like the one I write manually?

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");

I guess it's all about serialization, any idea how can I make it?

--Update--

I found this:

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

but it grabs only the last set it combines all sets in one (My bad, thanks to @Simon Mourier to pointing out my mistake !)

Upvotes: 10

Views: 1245

Answers (2)

Sinan
Sinan

Reputation: 908

Here's the solution:

On the client side

        // 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();

On the server side

    [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());
        }
    }

Global Modals (my solution structure)

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

Thanks for your help !!

Upvotes: 3

Black Hole
Black Hole

Reputation: 1382

I Find a way to see the query

you need make the query and save it in var

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

makeQuery have the value of Filter.Eq

Upvotes: 0

Related Questions