Unpacking JSON data with flexible data format

When consuming a JSON API in C#, I encountered an issue where the response's data structure varies based on the number of results returned from the query. To deserialize the response, I am using JSON.NET.

The JSON returned by the API is as follows:

Multiple Result Response:

{
  "response": {
    "result": {
      "Leads": {
        "row": [
          {
            "no": "1",
...
...
...

Single Result Response:

{
  "response": {
    "result": {
      "Leads": {
        "row": {
          "no": "1",
...
...
...

It is important to note that the "row" node can be either an array for multiple results or an object for single result.

Below are the classes used to serialize this data:

Classes:

public class ZohoLeadResponseRootJson
{
    public ZohoLeadResponseJson Response { get; set; }
}

public class ZohoLeadResponseJson
{
    public ZohoLeadResultJson Result { get; set; }
}

public class ZohoLeadResultJson
{
    public ZohoDataMultiRowJson Leads { get; set; }
}

public class ZohoDataMultiRowJson
{
    public List<ZohoDataRowJson> Row { get; set; }
}

public class ZohoDataRowJson
{
    public int No { get; set; }
    ...
}

Deserializing the "Multiple Result Response" works fine. However, when there is only one result, the data structure change causes an exception during deserialization:

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON 
object (e.g. {"name":"value"}) into type 
'System.Collections.Generic.List`1[MyNamespace.ZohoDataRowJson]' 
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) 
or change the deserialized type so that it is a normal .NET type (e.g. not a 
primitive type like integer, not a collection type like an array or List<T>) 
that can be deserialized from a JSON object. JsonObjectAttribute can also be 
added to the type to force it to deserialize from a JSON object.

Path 'response.result.Notes.row.no', line 1, position 44.

Is there a way to handle this scenario in Json.Net with attributes and without needing a custom converter?

Answer №1

This code snippet was created based on an insightful response to a related query.

public class CustomDataJsonConverter
{
    [JsonConverter(typeof(ArrayOrObjectConverter<CustomDataRowJson>))]
    public List<CustomDataRowJson> DataRows { get; set; }
}

public class ArrayOrObjectConverter<T> : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartArray)
        {
            return serializer.Deserialize<List<T>>(reader);
        }
        else if (reader.TokenType == JsonToken.StartObject)
        {
            return new List<T>
            {
                (T) serializer.Deserialize<T>(reader)
            };
        }
        else
        {
            throw new NotSupportedException("Unexpected JSON format encountered during deserialization");
        }
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dealing with asynchronous data in ngOnInit in Angular 4 when routing with parameters: tips and tricks

I'm currently facing an issue with loading data from my web api controller. The problem lies in the fact that I am using my API service, which is invoked from the ngOnInit function of the component. However, the view remains empty as the data retrieva ...

Is SignalR affected by the CORS same-origin policy?

After enabling CORS in my .NET core app, regular http requests are functioning properly. However, I am encountering CORS issues with SignalR when running my Angular app. Any suggestions or solutions would be greatly appreciated. Thank you in advance. Cros ...

Extract information from the website "angular.callbacks" using web crawling techniques

Looking to utilize R for scraping news from the following URL: "AlphaGo"&ss=fn&start=0). Below is the code I am working with: url <- "http://api.foxnews.com/v1/content/search?q=%22AlphaGo%22&fields=date,description,title,url,image,type,taxo ...

Consistent tree view nesting persists with each refresh

I have recently transitioned to Angular (7) from a C# background. Currently, I am using asp.net core 2.2 along with the default template that comes with a new Angular project (home, counter, fetch-data). The tree view is bound and retrieved from a controll ...

Dealing with Angular API Requests and Handling Cors Exception in C# Web API

My goal is to call an API on my C# Web API from my Angular Frontend. I have attempted making the call using both HTTP and HTTPS. When using HTTP, I encounter a CORS exception. On the other hand, when using HTTPS, I receive a CONNECTION CLOSED EXCEPTION. ...

Filtering JSON by a specific value in Ionic 2 app

Recently, I've started working with Ionic 2 and Angular. I'm trying to filter a JSON data to display only specific values, like getting users by gender. Below is the code snippet I tried: home.html <ion-list> <ion-item *ngFor="let ...

Utilizing Angular to render JSON data on the screen

Currently, I have my data saved in a database and am retrieving it in Angular. The problem arises when I attempt to display the data as I encounter an error. All I want is to exhibit the question in HTML using ngFor. Being new to Angular, any advice or gui ...

Managing numerous post requests with Angular

Dealing with a large form containing HTML input elements, I have implemented a functionality where a POST request is made to a WebAPI whenever there is a change in the input value. Sometimes, multiple POST requests are triggered within seconds, causing da ...

Attempting to retrieve JSON data and present it in a grid layout

I have a JSON file with the following data: { "rooms":[ { "id": "1", "name": "living", "Description": "The living room", "backgroundpath":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSrsU8tuZWySrSuRYdz7 ...

What is Angular's approach to handling a dynamic and unprocessed JSON object?

When a JSON file is placed under assets, accessing it using something like http://localhost:4200/myapp.com/assets/hello.json will fetch the JSON file directly without any graphical user interface. This indicates that Angular must be able to return a raw JS ...

Sending JSON data from Angular to WCF

Attempting to utilize the post method in Angular to send JSON data to a WCF service. The data is being sent in JSON format from Angular, however, the WCF service is receiving it as a null object. Is it possible to use the get method to send JSON data? Th ...

Bring JSON into Angular 7 application

For my Angular project, I've set up a localization service by importing JSON files. Following this recommended method, I updated my typings.d.ts as shown below: declare module "*.json" { const value: any; export default value; } Everything w ...

Error: Found an unconventional token "e" in JSON data at position 1 during parsing in JSON.parse function

Is there a way to retrieve a string value by calling an API in Angular? Here is my approach: Service file - public getRespondDashboardUrl(): Observable<any> { return this.http.get(`ref/RespondDashboardUrl`); } Component File respondDashboar ...

Leveraging Angular for Parsing JSON Data

I have a JSON object that I want to use in my code. The goal is to assign the values of certain properties from the JSON object to four variables in my Angular project. These variables are named as follows: authorText : string; titleText : string; duratio ...

Guide to showcasing images dynamically in Angular using .NET Core API and database

I am looking for a way to showcase an image that is stored in the database. Below is the code snippet showing how the image file gets uploaded to the database. public string UploadImage(IFormFile file) { if (file == null) thro ...

Establish a connection using Angular 4 HTTP POST to communicate with a Java REST API, as it is not permitted on the server

I am facing an issue with my Angular 4 client service that is calling a REST method declared on a Java server using a PostMapping annotation. When I make the call from Angular, it is not accepted by the server. However, when testing it on Postman, it work ...

Guide on transferring information obtained from a service to an Angular datatable

Recently, I started working on Angular 4 and encountered an issue while trying to display data from an Angular service in JSON format using angular-datatable. Despite trying various options, I am unable to get the data to display within the columns of the ...

Angular Binding issue - Unable to bind to 'ngModel' as it is not recognized as a valid property of 'input' element, despite the property being present

I have developed a component class like the one below and I am attempting to link the class fields to the template, but encountered the following error: ERROR in src/app/admin/projects/projects.component.html: 41:34 - error NG8002: Can't bind to &ap ...

Navigating through JSON data in an Angular application

I am currently facing an issue with uploading and parsing a JSON file in my Angular application. The problem lies in the fact that even though I can successfully upload the file, I am unable to access the data from it. To ensure the correct file is being ...

Handling JSON Data in JavaScript

In the script below, I have a json object that is being processed: $http({ url: '/mpdValidation/mpdValidate', method: "POST", data: { 'message' : mpdData } ).then(function(response) { console.log(response.data ...