Converting XML To C# Object From FTP

Reading a File over FTP is a common scenario. Best case scenario, the file is JSON and you can very easily convert it to a C# object using the serializer. What happens when it is XML? Converting it to a model requires a little more work. Here is how to read an XML file from an FTP folder and convert it to a C# object.

Let’s use this piece of XML as an example. This data is stored inside a file on the target FTP server. We want to download this data and access the data from a model we have created.

<Products>
	<Product>
		<id>123</id>
		<name>Test reading xml from ftp file using c#</name>
	</Product>
</Products>

This model is a representation of the XML above. We do not need to directly mimic the structure as we can define the root node as part of the serializer. Keep in mind that XML is case sensitive. The properties are lower case here to match the XML. I will go into detail below on a way to get around this if you would like upper case object properties.

public class Product
{
	public int id;
	public string name;
}

The process of fetching the file from the FTP server is fairly standard. The code below will prepare the request.

string ftpFilePath = "ftp://ftp.website.com/products.xml";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpFilePath);
request.Method = WebRequestMethods.Ftp.DownloadFile;

request.Credentials = new NetworkCredential("username", "pass");

Converting an FTP Stream to a C# Model

This part is not as hard as it seems but it is prone to failure. You will need to make sure the XML you are reading matches the C#. Any change in letter case will cause it to fail.

Since the XML is a list of product nodes wrapped inside a “Products” node, we can pass the root attribute into the serializer to let it know that this is the list element and we can decode from there.

List<Product> productList = null;
XmlSerializer serializer = new XmlSerializer(typeof(List<Product>), new XmlRootAttribute("Products"));
try
{
	using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
	{
		Stream responseStream = response.GetResponseStream();
		using (StreamReader reader = new StreamReader(responseStream))
		{
			productList = (List<Product>)serializer.Deserialize(reader);
		}
	}
}
catch(Exception e)
{
	//handle failure if something goes wrong while reading of deserializing the data. 
}

Converting an XML string to a C# Object

Since we are already on the topic of reading XML, what if you already have the XML string and do not need to download if from anywhere? The code is more or less the same. We still deserialize the data using a stream reader. If you have a piece of XML that is stored in a string object, convert it to a stream and follow the same process.

The code below will show you exactly how to convert the same piece of XML to a C# object. For this example, assume the data lives in a string called “xmlString”.

using (StringReader stringReader = new StringReader(xmlString))
{
	productList = (List<Product>)serializer.Deserialize(stringReader);
}

Deserialize XML With Case Insensitive

Sadly, XML is case sensitive and this must be enforced. There is a handy workaround to this though. The document from the Microsoft website here explains how to do this. If we work it into this example, lets say the XML is all lower case.

The XML below will not deserialize to a list of C# objects. It shouldn’t throw an error but the resulting list will contain 0 elements. Converting the class to use lower case is one option but this looks ugly and can cause issues if you have naming convention standards.

<products>
	<product>
		<id>123</id>
		<name>Case sensitivity test</name>
	</product>
</products>

Decorating the class with attributes will allow you to instruct the serializer to map an XML node with a specific name to a class or property on a model you have defined. To implement it in this example, simply add the attribute to the class to instruct it to use the lower case node instead of the class name.

[XmlType(TypeName = "product")]
public class Product
{
	[XmlElement("id")]
	public int Id;
	[XmlElement("name")]
	public string Name;
}

This is a fairly simple example overall and should give you a good idea on how to get started. More complex XML objects can really be a pain to parse. It is unfortunate but it is what it is. A nasty XML format will make you appreciate how great JSON has been for data transfer and translation.

Deserializing Double Nested XML To C# Object

One of the most frustrating things I have found with XML formats are when they are double nested for no observable reason. An array lives within a higher-level node with no additional children within this parent. Let’s use the following piece of XML as an example. For some reason, there is an additional wrapper node around the array of products.

<wrapper>
	<products>
		<product>
			<id>123</id>
			<name>Test reading xml from ftp file using c#</name>
		</product>
	</products>
</wrapper>

What was once a fairly simple process has now become a lot more complicated. The deserialization code will no longer work correctly because there is a new root node. To deal with this, you will need to come up with a proper C# hierarchy of classes that directly match the XML. The following C# classes could be used to deserialize the XML above.

[XmlRoot(ElementName = "product")]
    public class Product
    {
        [XmlElement(ElementName = "id")]
        public string Id { get; set; }
        [XmlElement(ElementName = "name")]
        public string Name { get; set; }
    }

    [XmlRoot(ElementName = "products")]
    public class Products
    {
        [XmlElement(ElementName = "product")]
        public List<Product> Product { get; set; }
    }

    [XmlRoot(ElementName = "wrapper")]
    public class Wrapper
    {
        [XmlElement(ElementName = "products")]
        public Products Products { get; set; }
    }

To generate the C# models faster and easier, there is a fantastic and free online tool called Xml2Csharp that will do all the heavy lifting for you. Provide the XML and it will generate the classes. Just make sure the example has multiple items for it to detect that you are working with an XML array and not an object.

Related Articles

Related Questions

WordPress Table of Contents Plus Not Working

I have been using this plugin for a while and i really like it. It seems to have completely stopped working recently. I can...

Function Keys Reversing Between Fn Actions And Normal

My keyboard has the usual F1 to F12 keys along the top. I use these for shortcuts in various applications. These keys also have...

Whirlpool Oven F6E6: Appliance Manager 1 Board Communication

I have a brand new Whirlpool oven W11I OM1 4MS2 H or (859991549450). I bought it alongside the microwave combi oven. I have had...

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Latest Tools

List Sorting Tool

Welcome to our innovative list ordering and management tool. This next-level platform enables you to sort a list of items in ascending or descending...

Sudoku Solver

Welcome to our free online Sudoku solving tool, an interactive platform for puzzle enthusiasts seeking a break from a Sudoku conundrum. This advanced platform...

Apply Image Filters To Image

Digital imagery in the modern world is all about reinforcing emotions and stories behind each photo we take. To amplify this storytelling, we are...

Add Watermark To Image

As the world is increasingly consumed by digital media, protecting your original images is paramount. We are thrilled to introduce you to our innovative...

CSV To Xml Converter

Welcome to our CSV to XML converter tool, a convenient and user-friendly solution for all your data conversion needs. This versatile tool on our...

RGB Image Splitter

Welcome to our innovative RGB Splitter - a unique image analyzer tool that offers an in-depth peek into the building blocks of your photos....

Latest Posts

Latest Questions