Arian Shahalami
Arian Shahalami

Reputation: 1449

Can't put Json results into a list

I'm using ASP.Net Core 2.2. My app gets data from an API which produces XML Content. In other side my app expect Json data so I have to convert XML to Json here is what I've done so far in MyController

public async Task<IActionResult> Index()
{
    List<ProductType> ProductTypes = new List<ProductType>();

    using (var httpClient = new HttpClient())
    {
            using (var response = await httpClient.GetAsync("https://localhost:44374/api/productTypes"))
            {
               string text = await response.Content.ReadAsStringAsync();
               XmlDocument doc = new XmlDocument();
               doc.LoadXml(text);
               var json = JsonConvert.SerializeXmlNode(doc);
               ProductTypes = JsonConvert.DeserializeObject<List<ProductType>>(json);
            }

    }
    return View("index", ProductTypes);
}

And this is ProductType model

public class ProductType
{

    public int Id { get; set; }
    public string Name { get; set; }
    public string Image { get; set; }

}

This is the content of Json variable in my controller when I get data from the API

"{\"ArrayOfProductType\":{\"@xmlns:i\":\"http://www.w3.org/2001/XMLSchema-instance\",\"@xmlns\":\"http://schemas.datacontract.org/2004/07/MyApi.Core.Models\",\"ProductType\":[{\"Id\":\"1\",\"Image\":\"/images/pizza.png\",\"Name\":\"Pizza\"},{\"Id\":\"2\",\"Image\":\"/images/burger.png\",\"Name\":\"Burger\"},{\"Id\":\"3\",\"Image\":\"/images/ad-salad.png\",\"Name\":\"Salad\"},{\"Id\":\"4\",\"Image\":\"/images/drinks.png\",\"Name\":\"Drinks\"}]}}"

And here is Index view

@model IEnumerable<ProductType>
@{
    ViewData["Title"] = "index";
}

<table class="table table-sm table-striped table-bordered m-2">
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var r in Model)
        {
            <tr>
                <td>@r.Id</td>
                <td>@r.Name</td>
            </tr>
        }
    </tbody>
</table>

But when I run the program i get this runtime error

JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Pizza.Models.ProductType]' 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) 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 'ArrayOfProductType', line 1, position 22.

What I'm missing here?

I found this link that indicate the problem but what is the solution?

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1

Upvotes: 0

Views: 551

Answers (2)

A. Nadjar
A. Nadjar

Reputation: 2543

Why using XmlDocument? Are you receiving XML format from API? As indicated in the comments, first it's a good idea to test your Index() with a dummy list.

you might try this and modify your controller's Index():

string text = await response.Content.ReadAsStringAsync();
ProductTypes= JsonConvert.DeserializeAnonymousType<List<ProductType>>(text , ProductTypes);

You can define a model DTO to wrap and transfer data. But in the first place, make sure your json matches the model.

*Note: If your API gives out only xml, you need to create some nested model classes to simulate the nested structure of the xml you receive. This thread shows a good example: How do Deserialize XML to json and json to c# classes?

Upvotes: 2

Jamshaid K.
Jamshaid K.

Reputation: 4547

The reason your json is not being deserialized is because you don't have a list in the response only, it is an object containing a list of products and two other json variables. according to the response you posted, Your models should Look like this:

public class ProductType
{
    public string Id { get; set; }
    public string Image { get; set; }
    public string Name { get; set; }
}

public class ArrayOfProductType
{
    [JsonProperty(PropertyName = "@xmlns:i")]
    public string xmlnsi { get; set; }
    [JsonProperty(PropertyName = "@xmlns")]
    public string xmlns { get; set; }
    public List<ProductType> ProductType { get; set; }
}

public class RootObject
{
    public ArrayOfProductType ArrayOfProductType { get; set; }
}

then deserialize the object like this:

var result = JsonConvert.DeserializeObject<RootObject>(json);

Upvotes: 0

Related Questions