When trying to deserialize Json I cannot figure a way around the error:
'Could not create an instance of type ConsoleApp1.IDisplayInstructions. Type is an interface or abstract class and cannot be instantiated. Path 'displayInstructions.AGB', line 4, position 34.'
I understand the meaning behind it; I need to instruct the Json deserializer which concrete class to use for the interface members. I just don't know how to do it. I tried using a JsonConstructor attribute, or use a custom deserializer - but I was not able to get either method to work.
There is another question that is similar (JSON.NET - how to deserialize collection of interface-instances?), but this is a field that is an interface, not the class itself.
using Newtonsoft.Json;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string jsonData = @"{
'Term' : 'john'
,'resourceTypes' : ['POL', 'CLM', 'WRK']
,'displayInstructions': {'AGB':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|resource_type| (|rank|) {0} / {1}'}
,'AGT':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|resource_type| (|rank|) {0} / {1}'}
,'AGY':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|resource_type| (|rank|) {0} / {1}'}
,'CLM':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|resource_type| (|rank|) {0} / {1}'}
,'PLU':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|resource_type| (|rank|) {0} / {1} / {2}'}
,'POL':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|resource_type| (|rank|) {0} / {1} / {2}'}
,'PRV':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|resource_type| (|rank|) {0} / {1}'}}
}";
SearchCriteria sc = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchCriteria>(jsonData);
}
}
interface ISearchCriteria
{
string Term { get; set; }
IEnumerable<string> ResourceTypes { get; set; }
IDisplayInstructions DisplayInstructions { get; set; }
}
class SearchCriteria : ISearchCriteria
{
public string Term { get; set; }
public IEnumerable<string> ResourceTypes { get; set; }
public IDisplayInstructions DisplayInstructions
{
get { return this.displayInstructions as IDisplayInstructions; }
set
{
this.displayInstructions = new DisplayInstructions();
foreach (var kvp in value)
{
this.displayInstructions.Add(kvp.Key, kvp.Value);
}
}
}
private DisplayInstructions displayInstructions;
[JsonConstructor]
public SearchCriteria(string term, IEnumerable<string> resourceTypes, IDisplayInstructions displayInstructions)
{
this.Term = term;
this.ResourceTypes = resourceTypes;
this.DisplayInstructions = displayInstructions;
}
}
interface IDisplayInstructions : IDictionary<string, IDisplayInstruction> { }
class DisplayInstructions : Dictionary<string, IDisplayInstruction> { }
interface IDisplayInstruction
{
IEnumerable<string> DisplayAttributes { get; set; }
string Format { get; set; }
}
class DisplayInstruction : IDisplayInstruction
{
public IEnumerable<string> DisplayAttributes { get; set; }
public string Format { get; set; }
}
}