0

I am trying to store a document in lowercase (both property name and value) in the CosmosDB. I just want to make it on the DocumentClient level. I found the below code to apply JsonSerializerSettings while creating the client object. But this will be applicable only on property names.

var client = new DocumentClient(new Uri(""), "", serializerSettings: new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
});

I can achieve this using the below code but I would like to do on the JsonSerializerSettings on DocumentClient.

var json = JsonConvert.SerializeObject(data);
var lowerCaseObject = json.ToLower();
Lews Therin
  • 3,707
  • 2
  • 27
  • 53
  • Perhaps a custom contract resolver, as mentioned here: https://stackoverflow.com/questions/6288660/ensuring-json-keys-are-lowercase-in-net/6288726 – Bryan Lewis Apr 10 '19 at 18:45
  • Thanks for the response, but this custom contract resolver will work only for property names. I want to convert the values as well. like ```var json = LowercaseJsonSerializer.SerializeObject(new { Foo = "Bar" }); // { "foo": "bar" }``` – Raju Donthula Apr 12 '19 at 06:19
  • any comments, please. – Raju Donthula Apr 26 '19 at 17:50

1 Answers1

0

You can do this using a custom converter, but depending on how complex your objects are, this can become quite complicated. For example, one that can handle any object with string and int values, as well as IEnumerables, would look something like this:

public class CaseConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value.GetType() == typeof(string) || value.GetType() ==  typeof(int))
        {
            writer.WriteValue(value.ToString().ToLower());
        }
        else
        {

            var enumerable = value as System.Collections.IEnumerable;

            if (enumerable != null)
            {

                writer.WriteStartArray();

                foreach (var item in enumerable)
                {
                    serializer.Serialize(writer, item);
                }

                writer.WriteEndArray();
            }
            else
            {
                writer.WriteStartObject();

                PropertyInfo[] properties = value.GetType().GetProperties();
                foreach (PropertyInfo pi in properties)
                {
                    writer.WritePropertyName(pi.Name.ToLower());
                    serializer.Serialize(writer, pi.GetValue(value));
                }

                writer.WriteEndObject();
            }
        }
    }

If you know what the object type you are serializing is, you can write your converter to be specific to that type instead of using reflection.

When calling the custom converter, you just add it to the serializer settings.

    var client = new DocumentClient(new Uri(""), "", serializerSettings: new JsonSerializerSettings
    {
        Converters = new List<JsonConverter>
        {
            new CaseConverter()
        }
    });
PerfectlyPanda
  • 3,271
  • 1
  • 6
  • 17