C# 将Json反序列化为具体类
在尝试反序列化Json时,我无法找到解决错误的方法: '无法创建类型为ConsoleApp1.IDisplayInstructions的实例。类型是接口或抽象类,无法实例化。路径'displayInstructions.AGB',第4行,位置34' 我理解它背后的含义;我需要指示Json反序列化器为接口成员使用哪个具体类。我只是不知道怎么做。我尝试使用JsonConstructor属性,或使用自定义反序列化程序,但两种方法都无法工作 还有一个类似的问题(),但这是一个作为接口的字段,而不是类本身C# 将Json反序列化为具体类,c#,json,json-deserialization,C#,Json,Json Deserialization,在尝试反序列化Json时,我无法找到解决错误的方法: '无法创建类型为ConsoleApp1.IDisplayInstructions的实例。类型是接口或抽象类,无法实例化。路径'displayInstructions.AGB',第4行,位置34' 我理解它背后的含义;我需要指示Json反序列化器为接口成员使用哪个具体类。我只是不知道怎么做。我尝试使用JsonConstructor属性,或使用自定义反序列化程序,但两种方法都无法工作 还有一个类似的问题(),但这是一个作为接口的字段,而不是类本身
使用Newtonsoft.Json;
使用System.Collections.Generic;
名称空间控制台EAPP1
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串jsonData=@”{
“术语”:“约翰”
,'resourceTypes':['POL','CLM','WRK']
,'displayInstructions':{'AGB':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'Format':'|资源类型|(|秩|){0}/{1}
,'AGT':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate','Format':'|资源类型|(|秩|){0}/{1}
,'AGY':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate','Format':'|资源类型|(|秩|){0}/{1}
,'CLM':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate','Format':'|资源类型|(|秩|){0}/{1}
,'PLU':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate','Format':'|资源类型|(|秩|){0}/{1}/{2}
,'POL':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate','Format':'|资源类型|(|秩|){0}/{1}/{2}
,'PRV':{'DisplayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate','Format':'|资源类型|(|秩|){0}/{1}}
}";
SearchCriteria sc=Newtonsoft.Json.JsonConvert.DeserializeObject(jsonData);
}
}
接口标准
{
字符串项{get;set;}
IEnumerable ResourceTypes{get;set;}
IDisplayInstructions显示指令{get;set;}
}
类搜索条件:ISearchCriteria
{
公共字符串项{get;set;}
公共IEnumerable ResourceTypes{get;set;}
公共IDisplayInstructions显示说明
{
获取{将this.displayInstructions作为IDisplayInstructions返回;}
设置
{
this.displayInstructions=新的displayInstructions();
foreach(var kvp值)
{
这个.displayInstructions.Add(kvp.Key,kvp.Value);
}
}
}
专用显示指令显示指令;
[JsonConstructor]
公共搜索条件(字符串术语、IEnumerable ResourceType、IDisplayInstructions和displayInstructions)
{
这个术语=术语;
this.ResourceTypes=ResourceTypes;
this.DisplayInstructions=DisplayInstructions;
}
}
接口IDisplayInstructions:IDictionary{}
类显示说明:字典{}
接口IDisplay指令
{
IEnumerable DisplayAttributes{get;set;}
字符串格式{get;set;}
}
类DisplayInstruction:IDisplayInstruction
{
公共IEnumerable显示属性{get;set;}
公共字符串格式{get;set;}
}
}
上面Matthew Groves()提供的帖子有一半答案,另一半以JsonDictionary属性()的形式出现。我能够保持接口方法,因为它确实适合我所追求的单元测试方法
最终代码:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
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}'}
,'POL' : {'displayAttributes' : ['AssuredName','PolicyNumber','DistributorName','EffectiveDate'] ,'format':'|resource_type| (|rank|) {0} / {1}'}}
}";
SearchCriteria des = JsonConvert.DeserializeObject<SearchCriteria>(jsonData);
}
}
interface ISearchCriteria
{
string Term { get; set; }
IEnumerable<string> ResourceTypes { get; set; }
IDisplayInstructions DisplayInstructions { get; set; }
}
public class ConfigConverter<I, T> : JsonConverter
{
public override bool CanWrite => false;
public override bool CanRead => true;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(I);
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
throw new InvalidOperationException("Use default serialization.");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jsonObject = JObject.Load(reader);
var deserialized = (T)Activator.CreateInstance(typeof(T));
serializer.Populate(jsonObject.CreateReader(), deserialized);
return deserialized;
}
}
class SearchCriteria : ISearchCriteria
{
public string Term { get; set; }
public IEnumerable<string> ResourceTypes { get; set; }
[JsonConverter(typeof(ConfigConverter<IDisplayInstructions, DisplayInstructions>))]
public IDisplayInstructions DisplayInstructions { get; set; }
}
interface IDisplayInstructions : IDictionary<string, IDisplayInstruction> { }
[JsonDictionary(ItemConverterType = typeof(ConfigConverter<IDisplayInstruction, DisplayInstruction>))]
class DisplayInstructions : Dictionary<string, IDisplayInstruction>, IDisplayInstructions
{
}
interface IDisplayInstruction
{
IEnumerable<string> DisplayAttributes { get; set; }
string Format { get; set; }
}
[JsonConverter(typeof(ConfigConverter<IDisplayInstruction, DisplayInstruction>))]
class DisplayInstruction : IDisplayInstruction
{
public IEnumerable<string> DisplayAttributes { get; set; }
public string Format { get; set; }
}
}
使用Newtonsoft.Json;
使用Newtonsoft.Json.Linq;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Xml;
名称空间控制台EAPP1
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串jsonData=@”{
“术语”:“约翰”
,'resourceTypes':['POL','CLM','WRK']
,'displayInstructions':{'AGB':{'displayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate'],'format':'|资源类型|(|秩|){0}/{1}
,'POL':{'displayAttributes':['AssuredName','PolicyNumber','DistributorName','EffectiveDate','format':'|资源类型|(|秩|){0}/{1}}
}";
SearchCriteria des=JsonConvert.DeserializeObject(jsonData);
}
}
接口标准
{
字符串项{get;set;}
IEnumerable ResourceTypes{get;set;}
IDisplayInstructions显示指令{get;set;}
}
公共类ConfigConverter:JsonConverter
{
公共覆盖boolcanwrite=>false;
public override bool CanRead=>true;
公共覆盖布尔CanConvert(类型objectType)
{
return objectType==typeof(I);
}
public override void WriteJson(JsonWriter writer,
对象值,JsonSerializer序列化程序)
{
抛出新的InvalidOperationException(“使用默认序列化”);
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var jsonObject=JObject.Load(读卡器);
var反序列化=(T)Activator.CreateInstance(typeof(T));
填充(jsonObject.CreateReader(),反序列化);
返回反序列化;
}
}
类搜索条件:ISearchCriteria
{
公共字符串项{get;set;}
公共IEnumerable ResourceTypes{get;set;}
[JsonConverter(类型(配置转换器))]