I have an XML string which is retrieved as an xml string from API call. I need to convert this into view model in my application so that this can be displayed in the view. however as the viewmodel only has few nodes/elements as there are in the xml document I get an exception thrown when I try to deserialize it. below is the code and the error.
API End Point returns this
<response>
<data>
<categories>
<category>
<id>1</id>
<name>hats</name>
</category>
</categories>
</data>
</response>
Code:
namespace CatApp.Models
{
[XmlRoot("Categories")]
public class CategoriesViewModel
{
public CategoriesViewModel()
{
_categories = new List<Category>();
}
private List<Category> _categories;
[XmlElement("Category")]
public List<Category> Categories
{
get { return _categories; }
set { value = _categories; }
}
public class Category
{
[XmlElement("Id")]
public int Id { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
}
}
}
public static async Task<CategoriesViewModel> GetAllCategories()
{
var model = new CategoriesViewModel();
try
{
var response = await client.GetStreamAsync(uri);
model = DeserializeXMLToObject<CategoriesViewModel>(response);
}
catch (Exception ex)
{
var exception = ex;
}
return model;
}
public static T DeserializeXMLToObject<T>(Stream stream)
{
T returnObject = default(T);
try
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
returnObject = (T)serializer.Deserialize(stream);
}
catch (Exception ex)
{
}
return returnObject;
}
Error at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
at CatApp.Controllers.HomeController.DeserializeXMLToObject[T](Stream stream) in C:\Users\umerh\source\repos\CatAPI\CatApp\Controllers\HomeController.cs:line 50
First, the element names in the C# attributes must match the element names in the XML. Case sensitive: Categories
not equal categories
and so on.
[XmlRoot("categories")] // <--
public class CategoriesViewModel
{
public CategoriesViewModel()
{
_categories = new List<Category>();
}
private List<Category> _categories;
[XmlElement("category")] // <--
public List<Category> Categories
{
get { return _categories; }
set { value = _categories; }
}
public class Category
{
[XmlElement("id")] // <--
public int Id { get; set; }
[XmlElement("name")] // <--
public string Name { get; set; }
}
}
Second, you can skip some of the xml elements as follows:
public static T DeserializeXMLToObject<T>(Stream stream)
{
T returnObject = default(T);
try
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (var xmlReader = XmlReader.Create(stream))
{
xmlReader.ReadToFollowing("categories"); // Skip elements before categories node
returnObject = (T)serializer.Deserialize(xmlReader);
}
}
catch (Exception ex)
{
}
return returnObject;
}