C# 不规则Json内容

C# 不规则Json内容,c#,asp.net,json,C#,Asp.net,Json,现在我正在解决一个问题,我从来没有遇到过。 我的模型中有一个带有此类的ASP.Net rest API: public class Filter<T> where T : class { [JsonProperty(PropertyName = "property1", Required = Required.Always)] public string Property1 { get; set; } [JsonProperty(Prop

现在我正在解决一个问题,我从来没有遇到过。 我的模型中有一个带有此类的ASP.Net rest API:

public class Filter<T> where T : class
{
    [JsonProperty(PropertyName = "property1", Required = Required.Always)]
    public string Property1 { get; set; }

    [JsonProperty(PropertyName = "property2", Required = Required.Always)]
    public string Property2 { get; set; } = null;

    [JsonProperty(PropertyName = "property3", Required = Required.Always)]
    public string Property3 { get; set; }
问题是属性2,它一次是字符串,另一次是数组。我如何处理这类问题?
客户不会让步。属性总是被命名为property2。

您可以在JSON调用和筛选器类之间创建某种中介类,您将在其中检查属性类型,而不是立即映射它

然后,将Property2的类型改为array而不是string,并在使用class时检查属性的长度,以检查它是单个字符串还是数组


编辑:假设数组是字符串数组。如果没有,则对一般类(如对象)执行同样的操作。

您可以在JSON调用和筛选器类之间创建某种中介类,您将在其中检查属性类型,而不是立即映射它

然后,将Property2的类型改为array而不是string,并在使用class时检查属性的长度,以检查它是单个字符串还是数组


编辑:假设数组是字符串数组。如果没有,则对一般类(如对象)执行相同操作。

您可以使用
JsonConverter
进行此操作。转换器将检查它是否是数组,如果是,则返回它。如果不是,则创建一个并添加唯一的值作为该数组中的第一个对象

internal class MyConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(List<T>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken jtoken = JToken.Load(reader);

        if (jtoken.Type == JTokenType.Array)
        {
            return jtoken.ToObject<List<T>>();
        }
        else
        {
            return new List<T> { jtoken.ToObject<T>() };
        }
    }

    public override bool CanWrite
    {
        get
        {
            return false;
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
测试

string json_with_array = "[ { \"property1\": \"xxxx\", \"property2\": \"xxxx\", \"property3\": \"xxxx\" }, { \"property1\": \"xxxx\", \"property2\": [\"xxxx\",\"yyyy\"], \"property3\": \"xxxx\" } ]";
string json_without_array = "[ { \"property1\": \"xxxx\", \"property2\": \"xxxx\", \"property3\": \"xxxx\" }, { \"property1\": \"xxxx\", \"property2\": \"zzzz\", \"property3\": \"xxxx\" } ]";

List<TestClass> list1 = JsonConvert.DeserializeObject<List<TestClass>>(json_with_array);
List<TestClass> list2 = JsonConvert.DeserializeObject<List<TestClass>>(json_without_array);

List<TestClass> merged_list = list1.Concat(list2).ToList();

string merged_json = JsonConvert.SerializeObject(merged_list);
[
  {
    "property1": "xxxx",
    "property2": [
      "xxxx"
    ],
    "property3": "xxxx"
  },
  {
    "property1": "xxxx",
    "property2": [
      "xxxx",
      "yyyy"
    ],
    "property3": "xxxx"
  },
  {
    "property1": "xxxx",
    "property2": [
      "xxxx"
    ],
    "property3": "xxxx"
  },
  {
    "property1": "xxxx",
    "property2": [
      "zzzz"
    ],
    "property3": "xxxx"
  }
]

您可以为此使用
JsonConverter
。转换器将检查它是否是数组,如果是,则返回它。如果不是,则创建一个并添加唯一的值作为该数组中的第一个对象

internal class MyConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(List<T>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken jtoken = JToken.Load(reader);

        if (jtoken.Type == JTokenType.Array)
        {
            return jtoken.ToObject<List<T>>();
        }
        else
        {
            return new List<T> { jtoken.ToObject<T>() };
        }
    }

    public override bool CanWrite
    {
        get
        {
            return false;
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
测试

string json_with_array = "[ { \"property1\": \"xxxx\", \"property2\": \"xxxx\", \"property3\": \"xxxx\" }, { \"property1\": \"xxxx\", \"property2\": [\"xxxx\",\"yyyy\"], \"property3\": \"xxxx\" } ]";
string json_without_array = "[ { \"property1\": \"xxxx\", \"property2\": \"xxxx\", \"property3\": \"xxxx\" }, { \"property1\": \"xxxx\", \"property2\": \"zzzz\", \"property3\": \"xxxx\" } ]";

List<TestClass> list1 = JsonConvert.DeserializeObject<List<TestClass>>(json_with_array);
List<TestClass> list2 = JsonConvert.DeserializeObject<List<TestClass>>(json_without_array);

List<TestClass> merged_list = list1.Concat(list2).ToList();

string merged_json = JsonConvert.SerializeObject(merged_list);
[
  {
    "property1": "xxxx",
    "property2": [
      "xxxx"
    ],
    "property3": "xxxx"
  },
  {
    "property1": "xxxx",
    "property2": [
      "xxxx",
      "yyyy"
    ],
    "property3": "xxxx"
  },
  {
    "property1": "xxxx",
    "property2": [
      "xxxx"
    ],
    "property3": "xxxx"
  },
  {
    "property1": "xxxx",
    "property2": [
      "zzzz"
    ],
    "property3": "xxxx"
  }
]

您必须使用更通用的类型,如
object
。然后在运行时键入检查,如
如果(filter.Property2是字符串值){}
您是否尝试使用对象类型:
公共对象Property2{get;set;}
您必须使用更通用的类型,如
对象
。然后在运行时键入检查它,如
如果(filter.Property2是字符串值){}
是否尝试使用对象类型:
公共对象Property2{get;set;}