C# 如何添加两个同名属性,以便能够反序列化两种不同的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[]

我必须解析一个JSON元素;有时是单个对象,有时是一组对象。我不想为每个场景创建一个单独的类,而是希望将其放在一个类中

 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; }
}