0

Is there any standard way of handling JSON responses that contain a common field which could be returned as Array (JArray) or Object (JObject)?

Sample: Both responses come from the same endpoint. If request failed response 1 (field data => of type array)

{
 "code": "1",
 "message": "Chatterjee",
 "data": [{"test"}],
}

If request was successfull response 2 (field data => of type object)

{
 "code": "1",
 "message": "Chatterjee",
 "data": {
           "name": "test"
  },
}

Right now I have two types which I use for deserialization.

public abstract class PushHubBaseResult
{
    public PushHubErrorCode Code { get; set; }
    public bool Success { get; set; }
    public string Message { get; set; }
    public abstract object GetData();
}

public class PushHubResult : PushHubBaseResult
{
    public JArray Data { get; set; }

    public override object GetData()
    {
        return Data;
    }
}

public class PushHubResultTransfer : PushHubBaseResult
{
    public JObject Data { get; set; }
    public override object GetData()
    {
        return Data;
    }
}

Depending on the request success I will have one or two deserializations.

IRestResponse<PushHubResultTransfer> result = client.Deserialize<PushHubResultTransfer>(response);

        if (result.IsSuccessful)
            return result.Data;
        else
        {
            // Try to deserialize failed response
            IRestResponse<PushHubResult> resultFailed = client.Deserialize<PushHubResult>(response);

            if (resultFailed.Data != null)
                return resultFailed.Data;

        }

How can I handle it by just having one deserilization? Like:

IRestResponse<TypeX> result = client.Deserialize<TypeX>(response);

        if (result.IsSuccessful)
            return result.Data;
        else
        {
            if (resultFailed.Data != null)
                return resultFailed.Data;
        }

Update:

I switched to "dynamic" to make it work with a single class. Because there is no casting done on the backend. It is forwarded to the JS Client 1:1 in this case.

 public class PushHubResult
{
    public PushHubErrorCode Code { get; set; }
    public bool Success { get; set; }
    public string Message { get; set; }
    public dynamic Data { get; set; }
}
Matthias Reisner
  • 581
  • 1
  • 6
  • 25
  • 1
    Does this answer your question? [How to handle both a single item and an array for the same property using JSON.net](https://stackoverflow.com/questions/18994685/how-to-handle-both-a-single-item-and-an-array-for-the-same-property-using-json-n) – Drag and Drop Nov 14 '19 at 10:28
  • and https://stackoverflow.com/questions/5224697/deserializing-json-when-sometimes-array-and-sometimes-object?noredirect=1&lq=1 – Drag and Drop Nov 14 '19 at 10:30
  • There is no built in way. We have to create a Custom converter for that. The one in the duplicate target seems ti be largly used https://learn.microsoft.com/tr-tr/dotnet/api/microsoft.crm.unifiedservicedesk.dynamics.singlevaluearrayconverter-1?view=dynamics-usd-3. – Drag and Drop Nov 14 '19 at 10:34

1 Answers1

0

You should use Newtonsoft.Json

Following code will give you "oj" array from Json and then get desired parameter from that aray.

JObject oj = JObject.Parse(Json);
JsonValue message = JsonValue.Parse(oj["message"].ToString());
Atisam Hameed
  • 31
  • 1
  • 6