This is a question related to inheritance of C# objects, but in the context of a protected method Newtonsoft.Json.Serialization.DefaultContractResolver
I followed the advice of this post on how to use mapping properties for serializing using Newtonsoft library. DefaultContractResolver usage
I created classes AbstractContractResolver, AbstractContractResolverFromFile, CustomClassImplementedContractResolver (custom named here for example purpose)
public abstract class AbstractContractResolver : DefaultContractResolver{
protected Dictionary<string, string> PropertyMappings {get { return this.getPropertyMappings(); }}
protected override string ResolvePropertyName(string propertyName)
{
string resolvedName = null;
var resolved = this.getPropertyMappings().TryGetValue(propertyName, out resolvedName);
return (resolved) ? propertyName : base.ResolvePropertyName(propertyName);
}
}
public abstract class AbstractContractResolverFromFile : AbstractContractResolver{
public AbstractContractResolverFromFile(string mapperFileName){
if(string.IsNullOrEmpty(mapperFileName)){
throw new InvalidOperationException(string.Format("The abstract class {0} uses a mapper file as input to resolve and populate properties. Please specify a valid mapper file!", this.GetType()));
}
this.MapperFileName = mapperFileName;
}
protected new virtual string ResolvePropertyName(string propertyName)
{
string field = propertyName;
if(this.PropertyMappings.Any() && this.PropertyMappings.ContainsKey(propertyName)){
field = this.PropertyMappings[propertyName];
}
else{
field = base.ResolvePropertyName(propertyName);
}
return field;
}
public class CustomClassImplementedContractResolver : AbstractContractResolverFromFile{
public CustomClassImplementedContractResolver (string mapperFileName) : base(mapperFileName){
}
protected override string ResolvePropertyName(string propertyName)
{
return base.ResolvePropertyName(propertyName);
}
The CustomClassImplementedContractResolver inherits AbstractContractResolverFromFile which inherits from the other class and so on.
I use it like this:
string mapperfile = "filepath/to/file.json";
CustomClassImplementedContractResolver contractResolver = new CustomClassImplementedContractResolver(mapperfile);
// Custom implementation to store mappings (PropertyName, FieldSource) in a Dictionary<string, string>
await contractResolver.PopulatePropertyMappings();
// Reading JSON and deserializing
using(TextReader tr = new StreamReader(jsonfile)){
string jsoncontent = await tr.ReadToEndAsync();
try{
var settings = new JsonSerializerSettings();
// Set the ContractResolver
settings.ContractResolver = contractResolver;
var item = JsonConvert.DeserializeObject<CustomClass>(jsoncontent, settings);
Issue -
Please have a look at my implementations of the protected function
ResolvePropertyName
in all these classes above and help me find the issue.
I think I am incorrectly overriding - and new
ing the method to override further...
My custom mappings created (from file) cannot be fetched because the incorrect ResolvePropertyName
is called...
When DeserializeObject executes, the code calls the
ResolvePropertyName
internally, but the currentcontractResolver
does not call the overridden method, it actually calls the first baseAbstractContractResolver.ResolvePropertyName
. In other words it I put breakpoints in all 4 functions (includingCustomClassImplementedContractResolver.ResolvePropertyName
), but it only executes theAbstractContractResolver
function.Strangely: I use Visual Studio Code and pressing F12 on
base.ResolvePropertyName
navigates correctly (as I expect my implementation to be) from each inherited function until base.