C # DataContractJsonSerializer fails when value can be an array or a single element

I am using DataContractJsonSerializer to parse json string in object hierarchy. The json line looks like this:

{
    "groups": [
        {
            "attributes": [
                {
                    "sortOrder": "1",
                    "value": "A"
                },
                {
                    "sortOrder": "2",
                    "value": "B"
                }
            ]
        },
        {
            "attributes": {
                "sortOrder": "1",
                "value": "C"
            }
        }
    ]
}

As you can see, the sub value for the attributes can be an array or a single element. I found the part of the code where the problem occurs:

[DataContract]
public class ItemGroup
{
    [DataMember(Name="attributes")]
    public List<DetailItem> Items  { get; set; }
}

This works for the first, but does not work in the second.

Does anyone have an answer to this question?

thank

+5
source share
3 answers

If you determine how JSON is created, make sure that the attributes are an array, even if it contains only one element. Then the second element will look and be perfectly understood.

    {
        "attributes": [{
            "sortOrder": "1",
            "value": "C"
        }]
    }
+3

, Json, . , Json.Net JsonObject this, :

JObject o = (JObject)JsonConvert.DeserializeObject(input);
dynamic json = new JsonObject(o);
foreach (var x in json.groups)
{
      var attrs = x.attributes;
      if (attrs is JArray)
      {
           foreach (var y in attrs)
           {
               Console.WriteLine(y.value);
           }
      }
      else
      {
          Console.WriteLine(attrs.value);
      }
 }
+3

DataContractJsonSerializer, JavaScriptSerializer JSON.Net, . L.B, JSON.Net, JsonObject. :

private List<ItemGroup> ParseItemGroupList(string input)
    {
        JObject json = JObject.Parse(input);

        List<ItemGroup> groups = new List<ItemGroup>();
        JArray gArray = json["groups"] as JArray;
        foreach (var gToken in gArray)
        {
            ItemGroup newGroup = new ItemGroup();
            JToken attrToken = gToken["attributes"] as JToken;
            if (attrToken is JArray)
            {
                newGroup.Items = attrToken.Children().Select(MapDetailItem()).ToList();
            }
            else
            {
                newGroup.Items = new List<DetailItem>() { MapDetailItem().Invoke(attrToken) };
            }

            groups.Add(newGroup);
        }

        return groups;
    }

    private static Func<JToken, DetailItem> MapDetailItem()
    {
        return json => new DetailItem
        {
            SortOrder = (string)json["sortOrder"],
            Value = (string)json["value"]
        };
    }

Hopefully someone will add the JSON.Net parameter so that he can forcefully deserialize the collection with a single element and not throw an exception. It's a shame that you will have to do all the parsing manually when there is only one small piece of JSON that is not parsed correctly automatically.

+1
source

All Articles