1

I have a NET Core MVC web application where I'm calling an API to show the results in my UI. I'm calling the API using an ajax call but after calling the API I get the following error message:

An unhandled exception occurred while processing the request. JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ProjectName.Models.ControllerName' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

JSON Result from API:

[
    [
        {
            "Col1": "Value",
            "Col2": "Value",
            "Col3": "Value",
            "Col4": [
                {
                    "Value": [
                        {}
                    ]
                },
                {
                    "Value": [
                        {}
                    ]
                }
            ],
            "Col5": "Value"
        }
    ],
    [
        {
            "Col1": "Value",
            "Col2": "Value",
            "Col3": "Value",
            "Col5": "Value"
         }
     ],
     [
        {
            "Col1": "Value",
            "Col2": "Value",
            "Col3": "Value",
            "Col4": [
                {
                    "Value": [
                        {}
                    ]
                },
                {
                    "Value": [
                        {}
                    ]
                 }
             ],
             "Col5": "Value"
        }
    ]
]

MyController

[HttpGet, ActionName("GetData")]
public async Task<IActionResult> GetReport()
{
    return this.Json(await _cuRepo.GetReportAsync("https://apiurlforcall/report"));
}

Repository

public async Task<IEnumerable<T>> GetReportAsync(string url)
{
    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Token", "apiToken");
        HttpResponseMessage response = await client.GetAsync(url);
        if (response.StatusCode == System.Net.HttpStatusCode.OK)
        {
            //jsonString is populated with the above JSON result
            var jsonString = await response.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<IEnumerable<T>>(jsonString);
        }
        else
            return null;
    }
}

AjaxCall (What I'm trying to do)

$.ajax({
    url: "Controller/GetData",
    data: {},
    method: "GET",
    success: function (data) {
        var json = data;
        var html = "";

        for (var x = 0; x < json.length; x++) {
            html += "<tr><td>" + json[x].Col1+ "</td><td>" + json[x].Col2+ "</td></tr>";
        }
        $('#MyTable').html("");
        $('#MyTable').html(html);
        console.log(json);
    }
});

To be honest, I don't have too much experience with net core, I'm trying to learn by doing this project but this issue is a big roadblock and I'm kind of lost.

4
  • Can you please add your class that you are using to deserialize and also the api response? Commented Jan 11, 2021 at 5:55
  • @ManpritSinghSahota Hello, I added the api response and what I'm using to deserialize is this IEnumerable<T> Commented Jan 11, 2021 at 6:06
  • Sometimes your Col4 in json is a list,and sometimes it is a string.Col4 cannot be like this. Commented Jan 11, 2021 at 6:08
  • @YiyiYou Sorry, my fault, Col4 always is a list, sometimes is returned by the API and sometimes not as the above example Commented Jan 11, 2021 at 6:12

2 Answers 2

2

You can do like this:

models:

public class Cols
    {
        public string  Col1 { get; set; }
        public string Col2 { get; set; }
        public string Col3 { get; set; }
        public List<Col4> Col4 { get; set; }
        public string Col5 { get; set; }

        
    }
    public class Col4
    {
        public List<Col> Value { get; set; }
    }
    public class Col
    { 

    }

change

return JsonConvert.DeserializeObject<IEnumerable<T>>(jsonString);

to

return JsonConvert.DeserializeObject<List<List<Cols>>>(jsonString);

Update:

1.change

public async Task<IEnumerable<T>> GetReportAsync(string url)

to

public async Task<List<List<Cols>>> GetReportAsync(string url)

2.change

var json = data;

to

var json = data[0];

3.change

html += "<tr><td>" + json[x].Col1+ "</td><td>" + json[x].Col2+ "</td></tr>";

to

html += "<tr><td>" + json[x].col1+ "</td><td>" + json[x].col2+ "</td></tr>";
Sign up to request clarification or add additional context in comments.

3 Comments

Doing this I'm getting "cannot implicitly convert System.Generics.List to System.Generics.IEnumerable<T>"
I do this to avoid the error return (IEnumerable<T>)JsonConvert.DeserializeObject<List<List<Cols>>>(jsonString); but now I'm getting this error: InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List1[System.Collections.Generic.List1[ProjectName.Models.Cols]]' to type 'System.Collections.Generic.IEnumerable`1[ProjectName.Models.Cols]'
I have updated my answer.You need to return Task<List<List<Cols>>>
1

You can use below class to deserialize your json:

public class DataObject
    {
        public ColDetails[][] MyData { get; set; }
    }

    public class ColDetails
    {
        public string Col1 { get; set; }
        public string Col2 { get; set; }
        public string Col3 { get; set; }
        public Col4[] Col4 { get; set; }
        public string Col5 { get; set; }
    }

    public class Col4
    {
        public Value[] Value { get; set; }
    }

    public class Value
    {
    }

Then, return the object that you want after converting to your class.

Use below code to deserialize:

JsonConvert.DeserializeObject<DataObject>(jsonString);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.