我正在使用Json.Net,我正在寻找有关如何在运行时反序列化期间更改JsonProperty名称的想法。为什么你会问,主要是因为我不喜欢有大量的" RootObject"浮动的类具有完全相同的结构。
考虑以下"根对象"。
public class Rootobject1
{
[JsonProperty("tasks")]
public List<Task> Data { get; set; }
}
public class Rootobject2
{
[JsonProperty("projects")]
public List<Project> Data { get; set; }
}
public class Rootobject3
{
[JsonProperty("countries")]
public List<Country> Data { get; set; }
}
看起来像是一大堆冗余代码。所以我在寻找选择。一些想到的是:
对某些简单条件逻辑使用属性参数的东西:
public class Rootobject<T>
{
[JsonProperty("projects", whenType=typeof(Project))]
[JsonProperty("tasks", whenType=typeof(Task))]
[JsonProperty("countries", whenType=typeof(Country))]
public List<T> Data { get; set; }
}
或者可能是运行时配置的内容?
var projects = JsonConvert.DeserializeObject<Rootobject<Project>>(json, RootName="projects")
var tasks = JsonConvert.DeserializeObject<Rootobject<Tasks>>(json, RootName="tasks")
所以我很好奇,有没有人想出一个创造性和优雅的方式处理这个?
答案 0 :(得分:2)
您可以使用自定义合约解析程序执行此操作。解析器可以有效地更改序列化程序在运行时查找的JSON属性名称。以下是您需要的代码:
class CustomResolver : DefaultContractResolver
{
string rootName;
public CustomResolver(string rootName)
{
this.rootName = rootName;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(RootObject<>))
{
JsonProperty prop = props.First(p => p.UnderlyingName == "Data");
prop.PropertyName = this.rootName;
}
return props;
}
}
下一部分是创建一个帮助方法,以便在反序列化时应用解析器:
public static RootObject<T> Deserialize<T>(string json, string rootName)
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CustomResolver(rootName);
return JsonConvert.DeserializeObject<RootObject<T>>(json, settings);
}
然后,您可以在问题中根据需要调用帮助程序:
RootObject<Project> projects = Deserialize<Project>(projectJson, "projects");