Json.Net: Html Helper Method not regenerating

This appears to be a bug with CamelCasePropertyNamesContractResolver. Its base class, DefaultContractResolver, has two constructors: a parameterless constructor, and a DefaultContractResolver (Boolean) version (just made obsolete in Json.NET 7.0). This parameter has the following meaning:

shareCache

  • Type: System.Boolean

    If set to true the DefaultContractResolverwill use a cached shared with other resolvers of the same type. Sharing the cache will significantly improve performance with multiple resolver instances because expensive reflection will only happen once. This setting can cause unexpected behavior if different instances of the resolver are suppose to produce different results. When set to false it is highly recommended to reuse DefaultContractResolver instances with the JsonSerializer.

The default is false.

Unfortunately, the default constructor for CamelCasePropertyNamesContractResolver sets the value to true:

public class CamelCasePropertyNamesContractResolver : DefaultContractResolver
{
    public CamelCasePropertyNamesContractResolver()
#pragma warning disable 612,618
        : base(true)
#pragma warning restore 612,618
    {
        NamingStrategy = new CamelCaseNamingStrategy
        {
            ProcessDictionaryKeys = true,
            OverrideSpecifiedNames = true
        };
    }
}

Further, there is no second constructor with the shareCache option. This breaks your SpecificFieldsResolver.

As a workaround, you could derive your resolver from DefaultContractResolver and use CamelCaseNamingStrategy to do the name mapping:

public class IndependentCamelCasePropertyNamesContractResolver : DefaultContractResolver
{
    public IndependentCamelCasePropertyNamesContractResolver()
        : base()
    {
        NamingStrategy = new CamelCaseNamingStrategy
        {
            ProcessDictionaryKeys = true,
            OverrideSpecifiedNames = true
        };
    }    
}

public class SpecificFieldsResolver : IndependentCamelCasePropertyNamesContractResolver
{
    // Remainder unchanged
}

Note that if you are using a version of Json.NET prior to 9.0, CamelCaseNamingStrategy does not exist. Instead a kludge nested CamelCasePropertyNamesContractResolver can be used to map the names:

public class IndependentCamelCasePropertyNamesContractResolver : DefaultContractResolver
{
    class CamelCaseNameMapper : CamelCasePropertyNamesContractResolver
    {
        // Purely to make the protected method public.
        public string ToCamelCase(string propertyName)
        {
            return ResolvePropertyName(propertyName);
        }
    }
    readonly CamelCaseNameMapper nameMapper = new CamelCaseNameMapper();

    protected override string ResolvePropertyName(string propertyName)
    {
        return nameMapper.ToCamelCase(propertyName);
    }
}

Leave a Comment