When doing UpsertAsync, the case of property/Key is not retained when the record is inserted in couchbase

If we run a statement as follows:

Blockquote
var upsertResult = await collection.UpsertAsync(“my-document”, new { NAME = “Ted”, AGE = 3 });
Blockquote

The record that is inserted, the case of Key is not retained:

Is there something wrong in the implementation or is this a backend issue ?

@_ragas_code

The behavior you are seeing is correct. The key is retained, as you can see it’s in the left column of the screenshot you provided. The key is not, however, added to the JSON document. It will serialize only fields that are a member of the POCO you provide.

If you desire the key to also be within the document, here is a common pattern:

public class Person
{
    public static string GetKey(long id) => $"person-{id}";

    public long Id { get; set; }
    public string Key => GetKey(Id);
    public string Name { get; set; }
    public int Age { get; set; }
}

This allows easy writing:

var upsertResult = await collection.UpsertAsync(person.Key, person);

And easy reading if you know the id:

var getResult = await collection.GetAsync(Person.GetKey(id));
var person = getResult.ContentAs<Person>();

@btburnett3 I think i wasnt clearly able to convey my problem statement, by key i meant property key, that is attribute to be exact, as u can see i sent attribute as 'NAME" but in database the attribute became ‘name’ .

@_ragas_code

By default, the Couchbase SDK uses Newtonsoft.Json with the CamelCasePropertyNamesContractResolver, which camel cases attribute names. This is handled automatically for you on both serialization and deserialization.

You may override this in one of two ways:

  1. Override a specific property using the [JsonProperty("NAME")] attribute.
  2. Override globally by supplying a custom serializer to the SDK

An example for global override:

var options = new ClusterOptions()
    .WithSerializer(new DefaultSerializer(new JsonSerializerSettings(), new JsonSerializerSettings());
3 Likes

Thanks @btburnett3 i was able to achieve my goal using the global solution using the following peace of code, for community to refer:

var options = new ClusterOptions().WithSerializer(new DefaultSerializer(
new JsonSerializerSettings(){
ContractResolver = new UppercaseContractResolver()
},
new JsonSerializerSettings(){
ContractResolver = new UppercaseContractResolver()
}
)).WithCredentials(couchbase_user,couchbase_password);
ICluster cluster = await Cluster.ConnectAsync($“couchbase://{couchbase_ip}”, options);

and UppercaseContractResolver as:

Blockquote
class UppercaseContractResolver : DefaultContractResolver
{
protected override string ResolvePropertyName(string propertyName)
{
return base.ResolvePropertyName(propertyName.ToUpper());
}
}

1 Like