C# 如何添加两个同名属性,以便能够反序列化两种不同的JSON格式?
我必须解析一个JSON元素;有时是单个对象,有时是一组对象。我不想为每个场景创建一个单独的类,而是希望将其放在一个类中C# 如何添加两个同名属性,以便能够反序列化两种不同的JSON格式?,c#,json,interface,javascriptserializer,C#,Json,Interface,Javascriptserializer,我必须解析一个JSON元素;有时是单个对象,有时是一组对象。我不想为每个场景创建一个单独的类,而是希望将其放在一个类中 public name name { get; set; } public name[] name { get; set; } 我提到了堆栈溢出中的类似问题。在某些情况下,使用接口来解析它 public class name : INames, INameLists { nameval INames.name { get; set; } nameval[]
public name name { get; set; }
public name[] name { get; set; }
我提到了堆栈溢出中的类似问题。在某些情况下,使用接口来解析它
public class name : INames, INameLists
{
nameval INames.name { get; set; }
nameval[] INameLists.name { get; set; }
}
但这对我不起作用。JSON元素没有解析,我得到一个异常
我希望条件是,当元素数组存在时,它必须解析为数组,否则解析为单个对象
请帮助解决这个问题。我认为这不会是一个重复的问题。如果是,请告诉我。您可以通过使用自定义类读取JSON元素并决定如何处理它来解决此问题:即,如果名称是数组,请在类上填充一个属性,或者如果它是单个对象,请填充另一个属性。 当然,如果没有像您在问题中所展示的那样在类上放置显式接口,则无法定义具有两个同名成员的类,因此属性必须具有不同的名称 我可以这样定义类:
public class NameObject
{
public string[] Names { get; set; }
public string Name
{
get { return (Names != null && Names.Length > 0) ? Names[0] : null; }
set { Names = (value != null) ? new string[] { value } : null; }
}
}
您可以在这里看到,Names
属性始终保存真实数据,而Name
属性只是在只有一个名称时的一种方便
下面是我编写转换器的方法:
public class NameObjectConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get { return new Type[] { typeof(NameObject) }; }
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
NameObject nameObj = new NameObject();
string singleName = GetValue<string>(dictionary, "name");
if (singleName != null)
{
nameObj.Name = singleName;
}
else
{
ArrayList arrayList = GetValue<ArrayList>(dictionary, "name");
nameObj.Names = (arrayList != null) ? arrayList.Cast<string>().ToArray() : null;
}
return nameObj;
}
private T GetValue<T>(IDictionary<string, object> dict, string key)
{
object value = null;
dict.TryGetValue(key, out value);
return value != null && typeof(T).IsAssignableFrom(value.GetType()) ? (T)value : default(T);
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
NameObject nameObj = (NameObject)obj;
Dictionary<string, object> dict = new Dictionary<string, object>();
if (nameObj.Names != null && nameObj.Names.Length == 1)
{
dict.Add("name", nameObj.Name);
}
else
{
dict.Add("name", nameObj.Names);
}
return dict;
}
}
下面是一个演示,展示了使用两种JSON格式运行的转换器。(我不得不在这里编造一些假的JSON,因为你在问题中没有提到实际的JSON是什么样子。)
您是否尝试使用属性
[JsonProperty(PropertyName=“name”)]
JSON本身是否超出了您的控制范围?这听起来像是一个可怕的使用JSON的时刻。您可能需要经历一个中间阶段,在这个阶段中动态加载JSON(例如,在JSON.NET中使用LINQ to JSON),将名称修改为不同的名称,然后通过常规的反序列化将其馈送。public name name{get;set;}[JsonProperty(PropertyName=“name”)]public name[]name1{get;set;}
我尝试使用此代码。但仍然有错误。我正在通过JavaScriptSerializer反序列化。反序列化
它对其余元素的工作正常,只有在这个条件下才会出现问题,如果我给单一名称对象,它就不会解析名称数组对象。如果我给名称数组对象,它就不会解析单个名称对象。@Jon Skeet,它不是动态的,如果是患者json数据,那么是单个名称对象,如果是医生json数据,那么是名称数组对象。所以对于两个场景,我需要创建单独的类。但是我在寻找单一的解决方案,而不是两个类。rest所有json结构都是相同的。仅在患者和医生数据中出现姓名问题。非常好的解释。它帮助我解决了我的问题。
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new List<JavaScriptConverter> { new NameObjectConverter() });
public class Program
{
public static void Main(string[] args)
{
string json = @"
{
""doctor"": {
""name"": ""Dr. Herbert Q. Cunningham III""
},
""patients"": {
""name"": [
""Joe Schmoe"",
""John Doe"",
""Steve Smith""
]
}
}";
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new List<JavaScriptConverter> { new NameObjectConverter() });
MedicalData data = serializer.Deserialize<MedicalData>(json);
Console.WriteLine("Doctor's name: " + data.Doctor.Name);
Console.WriteLine("Patients' names: ");
foreach (string name in data.Patients.Names)
{
Console.WriteLine(" " + name);
}
}
}
public class MedicalData
{
public NameObject Doctor { get; set; }
public NameObject Patients { get; set; }
}