Reputation: 1449
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?
Upvotes: 0
Views: 551
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
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