C# 使用json.net动态反序列化对多种类型的json响应
我有一个简单的API,可以为不同的任务生成不同类型的配置,因此我希望找到一种使用if/else动态解析响应的方法。但是由于某些原因,配置没有反序列化,因为它已经是一个字符串,并且C# 使用json.net动态反序列化对多种类型的json响应,c#,json.net,C#,Json.net,我有一个简单的API,可以为不同的任务生成不同类型的配置,因此我希望找到一种使用if/else动态解析响应的方法。但是由于某些原因,配置没有反序列化,因为它已经是一个字符串,并且Serialize()再次执行该操作 因此,JsonConvert.DeserializeObject(jsonString)就不起作用了 这是我的密码: void Main() { var json = new ApiResponse {name = "name1", type = "a", config =
Serialize()
再次执行该操作
因此,JsonConvert.DeserializeObject(jsonString)
就不起作用了
这是我的密码:
void Main()
{
var json = new ApiResponse {name = "name1", type = "a", config = "{'title' : 'hello world!', 'id' : 1}"};
var jsonString = JsonConvert.SerializeObject(json);
Console.WriteLine(jsonString);
if (json.type == "a")
{
var handler = JsonConvert.DeserializeObject<typeAhandler>(jsonString);
handler.Dump();
}
else if(json.type == "b")
{
var handler = JsonConvert.DeserializeObject<typeBhandler>(jsonString);
handler.Dump();
}
}
public class ApiResponse
{
public string name { get; set; }
public string type {get; set;}
public string config {get;set;}
}
// Type A Handler
public class typeAhandler
{
public string name { get; set; }
public typeAconfig config { get; set; }
}
public class typeAconfig
{
public string title { get; set; }
public int id { get; set; }
}
// Type B Handler
public class typeBhandler
{
public string name { get; set; }
public typeBconfig config { get; set; }
}
public class typeBconfig
{
public string[] items { get; set; }
}
void Main()
{
var json=new-ApiResponse{name=“name1”,type=“a”,config=“{'title':'hello world!','id':1}”;
var jsonString=JsonConvert.SerializeObject(json);
Console.WriteLine(jsonString);
如果(json.type==“a”)
{
var handler=JsonConvert.DeserializeObject(jsonString);
handler.Dump();
}
else if(json.type==“b”)
{
var handler=JsonConvert.DeserializeObject(jsonString);
handler.Dump();
}
}
公开课回应
{
公共字符串名称{get;set;}
公共字符串类型{get;set;}
公共字符串配置{get;set;}
}
//键入一个处理程序
公共类TypeHandler
{
公共字符串名称{get;set;}
公共类型配置{get;set;}
}
公共类类型图
{
公共字符串标题{get;set;}
公共int id{get;set;}
}
//B型处理器
公共类typeBhandler
{
公共字符串名称{get;set;}
公共类型配置配置{get;set;}
}
公共类类型配置
{
公共字符串[]项{get;set;}
}
在3天内,我发布了4次不同问题的相同答案:-)
使用特定的JsonConvert类:类程序
{
静态void Main(字符串[]参数)
{
var json=new-ApiResponse{Name=“name1”,Type=“a”,Config=“{'title':'hello world!','id':1}”;
//var json=new-ApiResponse{Name=“name1”,Type=“b”,Config=“{'items':['item1','item2']}”;
字符串apiResult=JsonConvert.SerializeObject(json);
var deserialized=JsonConvert.DeserializeObject
这是当类型:b
考虑按以下方式进行-
public static object DeserializeHandler(string jsonString, IDictionary<string, Type> handlers)
{
var jsonObject = JsonConvert.DeserializeObject<JToken>(jsonString);
var type = jsonObject["type"].ToString();
var handlerType = handlers[type];
var config = jsonObject["config"].ToString();
var handler = JsonConvert.DeserializeObject(config, handlerType);
return handler;
}
维护处理程序字典,以避免if…else
public static void Main(string[] args)
{
var json = new ApiResponse { name = "name1", type = "a", config = "{'title' : 'hello world!', 'id' : 1}" };
var jsonString = JsonConvert.SerializeObject(json);
Console.WriteLine(jsonString);
IDictionary<string, Type> handlers = new Dictionary<string, Type>
{
{ "a", typeof(typeAconfig) },
{ "b", typeof(typeBconfig) }
};
var handler = DeserializeHandler(jsonString, handlers);
}
publicstaticvoidmain(字符串[]args)
{
var json=new-ApiResponse{name=“name1”,type=“a”,config=“{'title':'hello world!','id':1}”;
var jsonString=JsonConvert.SerializeObject(json);
Console.WriteLine(jsonString);
IDictionary handlers=新字典
{
{“a”,typeof(typeAconfig)},
{“b”,typeof(typeBconfig)}
};
var handler=反序列化处理程序(jsonString,handlers);
}
函数反序列化处理程序如下所示-
public static object DeserializeHandler(string jsonString, IDictionary<string, Type> handlers)
{
var jsonObject = JsonConvert.DeserializeObject<JToken>(jsonString);
var type = jsonObject["type"].ToString();
var handlerType = handlers[type];
var config = jsonObject["config"].ToString();
var handler = JsonConvert.DeserializeObject(config, handlerType);
return handler;
}
公共静态对象反序列化处理程序(字符串jsonString,IDictionary处理程序)
{
var jsonObject=JsonConvert.DeserializeObject(jsonString);
var type=jsonObject[“type”].ToString();
var handlerType=handlers[type];
var config=jsonObject[“config”].ToString();
var handler=JsonConvert.DeserializeObject(配置,handlerType);
返回处理程序;
}
我会这样做:
static void Main()
{
var json=new-ApiResponse{name=“name1”,type=“a”,config=“{'title':'hello world!','id':1}”;
var jsonString=JsonConvert.SerializeObject(json);
Console.WriteLine(jsonString);
如果(json.type==“a”)
{
var handler=JsonConvert.DeserializeObject(jsonString);
//handler.Dump();
}
else if(json.type==“b”)
{
var handler=JsonConvert.DeserializeObject(jsonString);
//handler.Dump();
}
}
公开课回应
{
公共字符串名称{get;set;}
公共字符串类型{get;set;}
公共字符串配置{get;set;}
}
//键入一个处理程序
公共类TypeHandler
{
[JsonProperty(“名称”)]
公共字符串名称{get;set;}
[JsonIgnore]公共类型配置{get;set;}
[JsonProperty(“配置”)]
公共动态配置
{
set=>config=JsonConvert.DeserializeObject(值);
}
}
公共类类型图
{
公共字符串标题{get;set;}
公共int id{get;set;}
}
//B型处理器
公共类typeBhandler
{
[JsonProperty(“名称”)]
公共字符串名称{get;set;}
[JsonIgnore]
公共类型配置配置{get;set;}
[JsonProperty(“配置”)]
公共动态配置
{
set=>config=JsonConvert.DeserializeObject(值);
}
}
公共类类型配置
{
公共字符串[]项{get;set;}
}
关键是将配置类型以动态方式公开给JSONCOMVERT,然后在后台将其转换为您想要的类型并在应用程序中使用它我不完全清楚您想要什么,但您可以使用自定义属性执行类似操作,以避免使用if/else和反射来进行对象构造
internal class Program
{
public static void Main(string[] args)
{
var json = new ApiResponse { Name = "name1", Type = "a", Config = "{'title' : 'hello world!', 'id' : 1}" };
var jsonString = JsonConvert.SerializeObject(json);
ParseAndDumpConfig(jsonString);
json = new ApiResponse { Name = "name2", Type = "b", Config = "{'Items' : ['Item-1', 'Item-2', 'Item-3']}" };
jsonString = JsonConvert.SerializeObject(json);
ParseAndDumpConfig(jsonString);
}
private static void ParseAndDumpConfig(string jsonString)
{
Console.WriteLine();
Console.WriteLine("Parsing Api Response:");
Console.WriteLine(jsonString);
var json = JsonConvert.DeserializeObject<ApiResponse>(jsonString);
if (_typeMap.TryGetValue(json.Type, out var t))
{
var config = JsonConvert.DeserializeObject(json.Config, t);
Type genericType = typeof(TypeHandler<>).MakeGenericType(t);
var constructedObject = Activator.CreateInstance(genericType, new object[] { json.Name, config });
var result = Convert.ChangeType(constructedObject, genericType);
Console.WriteLine($"Parsed to [{result.GetType().FullName}]:");
Console.WriteLine(result);
}
else
{
Console.WriteLine($"Config map for \"{json.Type}\" not found.");
}
}
private static readonly Dictionary<string, Type> _typeMap = Assembly.GetExecutingAssembly().GetTypes()
.Where(x => x.CustomAttributes.Any(y => y.AttributeType == typeof(DeserializeTypeMapAttribute)))
.ToDictionary(x => x.GetCustomAttribute<DeserializeTypeMapAttribute>().Name);
}
public class ApiResponse
{
public string Name { get; set; }
public string Type { get; set; }
public string Config { get; set; }
}
public class TypeHandler<TConfig>
{
public string Name { get; set; }
public TConfig Config { get; set; }
public TypeHandler(string name, TConfig config)
{
Name = name;
Config = config;
}
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
[DeserializeTypeMap("a")]
public class TypeAconfig
{
public string Title { get; set; }
public int Id { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
[DeserializeTypeMap("b")]
public class TypeBconfig
{
public string[] Items { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
[AttributeUsage(AttributeTargets.Class)]
public class DeserializeTypeMapAttribute : Attribute
{
public string Name { get; }
public DeserializeTypeMapAttribute(string name)
{
Name = name;
}
}
内部类程序
{
公共静态void Main(字符串[]args)
{
var json=new-ApiResponse{Name=“name1”,Type=“a”,Config=“{'title':'hello world!','id':1}”;
var jsonString=JsonConvert.SerializeObject(json);
ParseAndDumpConfig(jsonString);
json=新的ApiResponse{Name=“name2”,Type=“b”,Config=“{'Items':['Item-1','Item-2','Item-3']}”;
jsonString=JsonConvert.SerializeObject(json);
ParseAndDumpConfig(jsonString);
}
私有静态void ParseAndDumpConfig(字符串jsonString)
{
Console.WriteLine();
WriteLine(“解析Api响应:”);
Console.WriteLine(jsonString);
var json=JsonConvert.DeserializeObject(jsonString);
if(_typeMap.TryGetValue(json.Type,out var t))
{
var config=JsonConvert.DeserializeObject(json.config,t);
Type genericType=typeof(TypeHandler)。MakeGenericType(t);
var constructedObject=Activato