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
DefaultContractResolver
will 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 reuseDefaultContractResolver
instances with theJsonSerializer
.
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);
}
}