Search code examples
c#jsoncouchbase

Updateasync does not support JsonObject


I am using C# Couchbase SDK. And I encountered some panic situation as follows.

I have a string like

string jsonString = """
            {
                "Product": "abc",
                "Price": 100
            }
            """;

And I convert it to JsonObject by means of

JsonObject jsonToProduce = JsonSerializer.Deserialize<JsonObject>(jsonString);

and I want to insert the above JsonObject to Couchbase. I wrote

await collection.UpsertAsync("1", jsonToProduce);

An error occurred that

Newtonsoft.Json.JsonSerializationException: 'Self referencing loop detected for property 'parent' with type 'System.Text.Json.Nodes.JsonObject'. Path 'product'.'

I saw some post that one may need to config the option of JsonSerializer like

var options = new JsonSerializerOptions
{
    ReferenceHandler = ReferenceHandler.Preserve
};

or with ReferenceHandler = ReferenceHandler.IgnoreCycles in place of ReferenceHandler = ReferenceHandler.Preserve

Anyway, both do not work for me, the same error occurred. And I am using the package that using System.Text.Json; rather than NewtonSoft, but I don't think this is an issue.

Of course, for inserting/upserting a document to Couchbase, a way to do that is like

var something = new { Product = "abc", Price = 1 };

and then

await collection.UpsertAsync("1", something);

this will surely work, but sometimes this is not practical for me, since I will have some JsonObject to work with. It is not possible to me to write out all the "keys" and "values" from the JsonObject.

Another tricky thing is that, if I do directly that

await collection.UpsertAsync("1", jsonString);

the resulting document in Couchbase will look like this

"{\r\n    \"Product\": \"abc\",\r\n    \"Price\": 100\r\n}"

The tricky thing is that, if I send directly the jsonString to Kafka as a message, it is good, no such \r\n things nor the extra " exist over there.


Solution

  • I think what's going on here is that you're mixing up System.Text.Json and Newtonsoft (or something like that).

    JsonObject jsonToProduce = JsonSerializer.Deserialize<JsonObject>(jsonString);
    

    This doesn't even compile for me because JsonSerializer.Deserialize(...) doesn't take string as a parameter. So, I'm not 100% sure what's going on that's causing your JsonSerializationException.

    But, with Newtonsoft, I think the way for you to go is:

    var json = JsonConvert.DeserializeObject<JObject>(jsonString);
    

    (Notice JObject instead of JsonObject).

    And then this Upsert works just fine:

    await collection.UpsertAsync("1", json);