JSON看起来像这样
{
"123": {
"Type": "IN",
"OUTAgentMACID": "00-14-22-01-23-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5901291
}
},
"124": {
"Type": "OUT",
"OUTAgentMACID": "00-14-22-01-31-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5991291
}
},
"125": {
"Type": "IN",
"INAgentMACID": "00-14-22-01-63-45",
"PlateNumber": {
"Image": "/poll/data/date1/img.png",
"Number": "ABC1234",
"TimeStamp": 6001239
}
}
}
可能的类结构为
public class PlateNumber
{
public string Image { get; set; }
public string Number { get; set; }
public int TimeStamp { get; set; }
}
public class Activity
{
public string Type { get; set; }
public string AgentMACID { get; set; }
public PlateNumber PlateNumber { get; set; }
}
public class SessionActivity
{
public Dictionary<int, Activity> Activities { get; set; }
}
助手看起来像这样
public class helpers : DefaultContractResolver
{
private Dictionary<string, string> PropertyMappings { get; set; }
public helpers()
{
PropertyMappings = new Dictionary<string, string>
{
{"INAgentMACID", "AgentMACID"},
{"OUTAgentMACID", "AgentMACID"},
};
}
protected override string ResolvePropertyName(string propertyName)
{
string resolvedName = null;
var resolved = this.PropertyMappings.TryGetValue(propertyName, out resolvedName);
return (resolved) ? resolvedName : base.ResolvePropertyName(propertyName);
}
}
现在,当我尝试像这样反序列化
var settings = new JsonSerializerSettings();
settings.ContractResolver = new helpers();
var activities = JsonConvert.DeserializeObject<SessionActivity>("Some.json"), settings);
activities
为空。
问题是AgentMACID
,因为JSON具有OUTAgentMACID
或INAgentMACID
取决于Type
请帮助我为此JSON设计类。
答案 0 :(得分:1)
我认为您不可能直接拥有一个表示json-的两个属性的属性(正如我在这里Make JsonPropertyAttribute allow multiple usages on same property所读)
我从这篇文章中了解到的是,您将不得不拥有另一个属性,该属性只是将值“转发”到所需属性。
示例:
public class Activity
{
public string Type { get; set; }
public string AgentMACID { get; set; }
private string AgentMACID2 { set { AgentMACID = value; } } // used to map the other field of json
public PlateNumber PlateNumber { get; set; }
}
在Contract Resolver中,您必须像以前一样映射过孔。在我添加的第二个字段中,它看起来可能像这样:
PropertyMappings = new Dictionary<string, string>
{
{"AgentMACID","OUTAgentMACID"},
{"AgentMACID2","INAgentMACID"}
};
并以此反序列化:
var activities = JsonConvert.DeserializeObject<Dictionary<int, Activity>>("json content", settings);
答案 1 :(得分:1)
1-从JSON反序列化字典
基于您的json对象:
{
"123": {
"Type": "IN",
"OUTAgentMACID": "00-14-22-01-23-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5901291
}
},
"124": {
"Type": "OUT",
"OUTAgentMACID": "00-14-22-01-31-45",
"PlateNumber": {
"Image": "/poll/data/date0/img.png",
"Number": "ABC1234",
"TimeStamp": 5991291
}
},
"125": {
"Type": "IN",
"INAgentMACID": "00-14-22-01-63-45",
"PlateNumber": {
"Image": "/poll/data/date1/img.png",
"Number": "ABC1234",
"TimeStamp": 6001239
}
}
}
您可以使用:反序列化字典:
var activities = JsonConvert.DeserializeObject<Dictionary<int, Activity>>("Some.json"), settings);
2.1-在一个C#属性中管理多个json属性名称
对于第二个问题,您可以像这样定义Activity
类:
public class Activity
{
public string Type { get; set; }
public string AgentMACID { get; set; }
// Optional: you can rename your property with this property attribute
// [JsonProperty("INAgentMACID")]
public string INAgentMACID { set { AgentMACID = value; } }
// Optional: you can rename your property with this property attribute
// [JsonProperty("OUTAgentMACID")]
public string OUTAgentMACID { set { AgentMACID = value; } }
public PlateNumber PlateNumber { get; set; }
}
2.2-您还可以像执行操作一样继承DefaultContractResolver:
public class RenamePropertySerializerContractResolver : DefaultContractResolver
{
private readonly Dictionary<Type, HashSet<string>> _ignores;
private readonly Dictionary<Type, Dictionary<string, string>> _renames;
public RenamePropertySerializerContractResolver()
{
_renames = new Dictionary<Type, Dictionary<string, string>>();
}
public void RenameProperty(Type type, string propertyName, string newJsonPropertyName)
{
if (!_renames.ContainsKey(type))
_renames[type] = new Dictionary<string, string>();
_renames[type][propertyName] = newJsonPropertyName;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (IsRenamed(property.DeclaringType, property.PropertyName, out var newJsonPropertyName))
property.PropertyName = newJsonPropertyName;
return property;
}
private bool IsRenamed(Type type, string jsonPropertyName, out string newJsonPropertyName)
{
Dictionary<string, string> renames;
if (!_renames.TryGetValue(type, out renames) || !renames.TryGetValue(jsonPropertyName, out newJsonPropertyName))
{
newJsonPropertyName = null;
return false;
}
return true;
}
}
最后使用您新的ContractResolver:
var jsonResolver = new RenamePropertySerializerContractResolver();
jsonResolver.RenameProperty(typeof(Activity), "INAgentMACID", "AgentMACID");
jsonResolver.RenameProperty(typeof(Activity), "OUTAgentMACID", "AgentMACID");
var serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = jsonResolver;
var activities = JsonConvert.DeserializeObject<IDictionary<int, Activity>>(json, serializerSettings);