25

I am using http://json.codeplex.com/ and I am talking to a Ruby based Rest API. Problem is that most of the properties have a ruby underscore naming convention. I am wondering if anyone knows of a way so that I can avoid having to Add lots of JsonProperty.

For example I want to avoid adding the JsonProperty attribute and have a convention built into the serializer settings so that it knows to try and map properties with an underscore in the to the .NET naming convention :)

public class Member
{
    [JsonProperty(PropertyName = "avatar_url")]
    public string AvatarUrl { get; set; }

    [JsonProperty(PropertyName = "twitter_screen_name")]
    public string TwitterScreenName { get; set; }

    [JsonProperty(PropertyName = "website_url")]
    public string WebSiteUrl { get; set; }
}

4 Answers 4

37

Update - September 2016:

Json.NET 9.0.1 has SnakeCaseNamingStrategy. You can use that to have twitter_screen_name style properties automatically.


Inherit from DefaultContractResolver and override ResolvePropertyName to format property names as you'd like.

CamelCasePropertyNamesContractResolver does a similar global change to property names.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks James will give it a shot and post my findings here for others who might run into this situation.
FYI, there is a potentially huge performance issue with contract resolvers with naming strategies in general. Massive decreases in throughput when using one (90TPS) vs. when not (600TPS).
Reuse the contract resolver. Creating a new one each time forces reflection to happen every serialization/deserialization.
30

Read this : http://nyqui.st/json-net-newtonsoft-json-lowercase-keys

public class UnderscoreMappingResolver : DefaultContractResolver 
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            return System.Text.RegularExpressions.Regex.Replace(
                propertyName, @"([A-Z])([A-Z][a-z])|([a-z0-9])([A-Z])", "$1$3_$2$4").ToLower(); 
        }
    }

1 Comment

This does not work for properties with two consecutive capital letters. ThisIsATest becomes this_is_atest.
14

As of version 9, a new naming strategy property exists to do this, and it has a built-in SnakeCaseNamingStrategy class. Use the code below and register contractResolver as SerializerSettings.ContractResolver.

var contractResolver = new DefaultContractResolver();
contractResolver.NamingStrategy = new SnakeCaseNamingStrategy();

That class does not include dictionaries by default, and it does not override any manually-set property values. Those are the two parameters that can be passed in the overload:

// true parameter forces handling of dictionaries
// false prevents the serializer from changing anything manually set by an attribute
contractResolver.NamingStrategy = new SnakeCaseNamingStrategy(true, false);

Comments

4

This one worked for me

var settings = new JsonSerializerSettings
{
    ContractResolver = new PascalCaseToUnderscoreContractResolver()
};
var rawJson = "{ test_property:'test' }"
var myObject = JsonConvert.DeserializeObject<MyObjectType>(rawJson, settings);

Using Humanizer function "Underscore"

https://www.nuget.org/packages/Humanizer/1.37.7

http://humanizr.net/#underscore

public class PascalCaseToUnderscoreContractResolver : DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName) => propertyName.Underscore();
}

MyObjectType class

public Class MyObjectType
{
    public string TestProperty {get;set;}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.