Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable Nancy's JSON to C# class auto case conversion for Dictionary<string, T>?

How can Nancy's automatic conversion between camel and Pascal casing during serialization to and deserialization from JSON be disabled for objects representing dictionaries in C# and JavaScript?

In my case the keys of these dictionaries are IDs that must not be changed by the automatic case conversion.

Additionally, these dictionaries themselves are values of other object's property names / keys.

Here is an example JavaScript object, where I want the auto case conversion for the object (.customers to .Customers and .addresses to .Addresses), but not for the ID-value sub-objects' keys (ID33100a00, abc433D123, etc.):

{
    customers: {
        ID33100a00: 'Percy',
        abc433D123: 'Nancy'
    },
    addresses: {
        abc12kkhID: 'Somewhere over the rainbow',
        JGHBj45nkc: 'Programmer\'s hell',
        jaf44vJJcn: 'Desert'
    }
}

These dictionary objects are all represented by Dictionary<string, T> in C#, e.g.:

Dictionary<string, Customer> Customers;
Dictionary<string, Address> Addresses;

Unfortunately setting

JsonSettings.RetainCasing = true;

would result in no auto case conversion at all.

I also tried to solve the problem by writing my own JavaScriptConverter as described in Nancy documentation, but the actual serialization/deserialization to/from strings for the keys of objects takes place somewhere else (because the converter does not handle JSON strings directly, but IDictionary<string, object> objects).

I read about a related "bug" (or behavior) here.

like image 558
RhinoDevel Avatar asked Oct 19 '22 01:10

RhinoDevel


1 Answers

In our projects we usually depend on Newtonsoft.Json for our serializing needs. And how we get the proper casing, is by creating a new class inheriting from JsonSerializer, like so:

public sealed class CustomJsonSerializer : JsonSerializer
{
    public CustomJsonSerializer()
    {    
        ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

And then register it with the Application like this:

protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
    base.ConfigureApplicationContainer(container);
    container.Register<JsonSerializer,CustomJsonSerializer>().AsSingleton();            
}

It also allows you to customize other bits of serialization, Like getting enums Serialized as strings:

public CustomJsonSerializer()
{
    Converters.Add(new StringEnumConverter());
    ContractResolver = new CamelCasePropertyNamesContractResolver();
}    
like image 200
hvattum Avatar answered Nov 14 '22 07:11

hvattum