3

I am communicating with an API that returns JSON containing either true, false or an array of string arrays. I wish to deserialize this JSON and store the boolean value, if there is one, in a class field called Success of data type bool, and the array, if there is one, in a field called Result of a custom data type.

What is the best to go about achieving this?

Some JSON:

[
    {"status":"ok","result":true},
    {
        "status":"ok",
        "result":
        [
            {"name":"John Doe","UserIdentifier":"abc","MaxAccounts":"2"}
        ]
    }
]

My Result class:

class Result
{
    string Name,
    string UserIdentifier,
    string MaxAccounts
}

Class for communicating with the Api:

class Api
{
    public string Status { get; set; }
    public Result[] Result { get; set; }
    public bool Success { get; set; }
}
Maritim
  • 2,111
  • 4
  • 29
  • 59
  • I was writing a reply to your last question (quarters of the year) do you want it or not? – varocarbas Aug 05 '13 at 18:20
  • Yeah sure, I just deleted it, because I apparently I was completely unable to make anyone understand what I was asking. Thanks. – Maritim Aug 05 '13 at 18:23
  • Just to make sure that I got the idea right: if you input the 6th month, you want as outputs 5 (first month of the quarter) and 8 (last month of the quarter). Am I right? – varocarbas Aug 05 '13 at 18:24
  • The first month of each quarter is jan/apr/jul/oct. The last month is mar/jun/sep/dec. If I input the the sixth month I would want the output to be the seventh month (july is the first month of the third quarter) and the sixth month, as june is the last month of the second quarter. – Maritim Aug 05 '13 at 18:28
  • OK. Small update regarding the quarters understanding but the idea is clear. Where might I write my answer? – varocarbas Aug 05 '13 at 18:29
  • Feel free to mail it to maritim at gmail dot com – Maritim Aug 05 '13 at 18:30
  • Well... that sounds a bit outside the community :) I meant where is your question now? – varocarbas Aug 05 '13 at 18:31
  • I deleted the question as I felt I was being badgered for my inability to express myself properly. I'll put it up again. – Maritim Aug 05 '13 at 18:32
  • 1
    Don't feel bad. I read your question and was more or less clear. A bit confusing perhaps. The best way to make a question clear is putting an example: like right now with me. I want the last month of the current quarter and the first one of the next quarter. For example: if I input 6... – varocarbas Aug 05 '13 at 18:34
  • It's okay that people think it's unclear, but I don't need the same message from five different people in 40 seconds. Question is soon up again. Thanks a lot for the effort! – Maritim Aug 05 '13 at 18:35
  • @varocarbas The question is back. – Maritim Aug 05 '13 at 18:39
  • OK. Give me some minutes. – varocarbas Aug 05 '13 at 18:43

2 Answers2

4

With JSON.NET you could write a custom JSON converter. For example you could have the following objects:

public class Root
{
    public string Status { get; set; }
    public Result Result { get; set; }
}

public class Result
{
    public bool? Value { get; set; }
    public Item[] Items { get; set; }
}

public class Item
{
    public string Name { get; set; }
    public string UserIdentifier { get; set; }
    public string MaxAccounts { get; set; }
}

and your JSON will be deserialized to a Root[].

Here's how the custom JSON converter may look like:

public class ResultConverter: JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Result);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Boolean)
        {
            return new Result
            {
                Value = (bool)reader.Value,
            };
        }

        return new Result
        {
            Items = serializer.Deserialize<Item[]>(reader),
        };
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // If you want to support serializing you could implement this method as well
        throw new NotImplementedException();
    }
}

and then:

class Program
{
    static void Main()
    {
        var json = 
        @"[
            {
                ""status"": ""ok"",
                ""result"": true
            },
            {
                ""status"": ""ok"",
                ""result"": [
                    {
                        ""name"": ""John Doe"",
                        ""UserIdentifier"": ""abc"",
                        ""MaxAccounts"": ""2""
                    }
                ]
            }
        ]";

        var settings = new JsonSerializerSettings();
        settings.Converters.Add(new ResultConverter());
        Root[] root = JsonConvert.DeserializeObject<Root[]>(json, settings);
        // do something with the results here
    }
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

create and arraylist using Api and Results objects. I have just tried this and it works.

        var api = new Api();
        var result = new Result();
        api.Status = "ok";
        api.Success = true;
        result.Name = "John Doe";
        result.UserIdentifier = "abc";
        result.MaxAccounts = "2";
        api.Result = new Result[1];
        api.Result[0] = result;
        var arrayList = new ArrayList() { new {api.Status, api.Success}, 
                        new { api.Status, api.Result} };
        var json = JsonConvert.SerializeObject(arrayList, Formatting.Indented);
yavuz
  • 332
  • 1
  • 4