【问题标题】:Deserialize JSON single string to array将 JSON 单个字符串反序列化为数组
【发布时间】:2015-07-02 14:01:50
【问题描述】:

我正在尝试反序列化我的 json 数据,但是我的类设置不正确我无权更改 json 响应,因此我需要编写一个函数来正确处理 json。

这是数据

{
  "blabla": {
    "-Score": "1",
    "-Ref": "50",
    "foo": {
      "-colour": "Yellow",
      "-ref": "y50"
    }
  }
}

但有时数据会是

    {
  "blabla": {
    "-Score": "1",
    "-Ref": "50",
    "foo": [
      {
        "-colour": "Yellow",
        "-ref": "y50"
      },
      {
        "-colour": "Green",
        "-ref": "g50"
      },
      {
        "-colour": "Red",
        "-ref": "r50"
      }
    ]
  }
}

此类适用于第一个数据

public class blabla
{
    public Foo Foo {get; set;}
}

这个类适用于第二个数据

public class blabla
{
    public Foo[] Foo {get; set;}
}

但是我怎样才能让课程同时适用于两者?

【问题讨论】:

  • “为了便于阅读”,如果您显示实际的 JSON,会远更好。你问我们如何反序列化我们想象这两个示例的 JSON 表示可能是什么。
  • 您对 JSON 格式有任何控制权吗? “有时它是一个数组,有时它不是”不是有史以来最合理的表示。 “始终是一个数组,即使只有一个”将使序列化和反序列化方面的工作更轻松。
  • 不幸的是,我完全无法控制它
  • 不确定这是否有用,但它似乎是一个类似的问题 - michaelcummings.net/mathoms/…
  • 如果可以使用 JSON.net,那么编写自定义转换器很容易。您的 blabla 类将具有 Foo[] 属性,您将使用自定义转换器检查 foo 属性并填充数组。

标签: c# json


【解决方案1】:

以下是基本类:

public class Test
{
    public Blabla blabla { get; set; }
}

public class Blabla
{
    public string _score { get; set; }
    public string _ref { get; set; }

    [JsonConverter(typeof(FooConverter))]
    public Foo[] foo { get; set; }
}

public class Foo
{
    public string _colour { get; set; }
    public string _ref { get; set; }
}

无论数据是什么,都将foo的类型设置为Foo[],并添加[JsonConverter(typeof(FooConverter))]使用自定义转换器。

这是自定义转换器:

public class FooConverter : JsonConverter
{
    // Declared as abstract in JsonConverter so must be overridden
    public override bool CanConvert(Type objectType) { return true; }

    // Declared as abstract in JsonConverter so must be overridden
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { }

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

        return token.Type == JToken.Array ? token.ToObject<Foo[]>() : new Foo[] { token.ToObject<Foo>() };
    }
}

在ReadJson 方法中,我们将数据加载到令牌中,并检查数据是数组还是普通对象。如果它已经是一个数组,我们只返回数组对象为Foo[],如果它是一个普通对象,我们返回一个包含我们普通对象的new Foo[]。

这是一个测试用例:

string json1 = @"{
                  ""blabla"": 
                    {
                      ""_score"": ""1"",
                      ""_ref"": ""50"",
                      ""foo"": 
                        {
                          ""_colour"": ""Yellow"",
                          ""_ref"": ""y50""
                        }
                    }
                }";

string json2 = @"{
                 ""blabla"": 
                    {
                      ""_score"": ""1"",
                      ""_ref"": ""50"",
                      ""foo"": 
                        [
                          {
                            ""_colour"": ""Yellow"",
                            ""_ref"": ""y50""
                          },
                          {
                            ""_colour"": ""Green"",
                            ""_ref"": ""g50""
                          },
                          {
                            ""_colour"": ""Red"",
                            ""_ref"": ""r50""
                          }
                        ]
                    }
                }";

Test test1 = JsonConvert.DeserializeObject<Test>(json1);
Test test2 = JsonConvert.DeserializeObject<Test>(json2);

您将始终有一个数组,但第一个测试用例中会有 1 个元素,第二个测试用例中有 3 个元素。

【讨论】:

    【解决方案2】:
    1. 转至json2csharp.com
    2. 粘贴您的 json 数据
    3. 生成类

    你去吧:)

    using Newtonsoft.Json;
    using (WebClient wc = new WebClient())
    {
        var json = wc.DownloadString(url);
        var t = JsonConvert.DeserializeObject<whateverClass.you.have.made>(json);
    }
    

    【讨论】:

    • 谢谢,但不行 - 如果您粘贴第一个数据,它会将其设置为一个字符串,如果您粘贴第二个数据,则将其作为一个数组。
    • 检查变量是否有元素呢?某事... if (t.response.foo.Count != 0)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    相关资源
    最近更新 更多