Development suggestions

I offer the following descriptive image to Rasmus Lerdorf, Anders Hejlsberg, Brendan Eich and all other people who might be maintaining, developing or creating new languages. Programming can be cold, logical and too intuitive (varies massively between languages). I offer a possible solution to this dilemma:
Language improvements

I hope some of you will implement these features in the future. Leave a comment if you do!

C# xml serializing

If you don’t think you’ll use ever use XML since we now live in the future think again. XML is very useful for sending data over network, especially when you don’t know the recipient. Serializing in C# is as easy as cake and as long as you decide the XML rules it takes 2 minutes to generate properly named XML-elements. The problem starts when you work with someone who keeps sending you poorly named XML and expects the same ¤!”#% back.

Not to worry, the .NET library makes it all incredibly easy to serialize. To take an example we’ll create a Person class and serialize it:

 
Person.cs

public class Person
{
    public int Age { get; set; }
 
    public string Name { get; set; }
 
    public List<string> NickNames { get; set; }
 
    public Person()
    {
        NickNames = new List<string>();
    }
}

We’ll create a class for generic serialization that looks like this:

GenericSerializer.cs

public class GenericSerializer
{
    /// <remark>
    /// I hate nested classes but I've never found a 
    /// use for this class outside of this situation
    /// </remark>
    private class Utf8StringWriter : StringWriter
    {
        public override Encoding Encoding
        {
            get { return Encoding.UTF8; }
        }
    }
 
    public static string Serialize<T>(T obj)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        using (StringWriter writer = new Utf8StringWriter())
        {
            serializer.Serialize(writer, obj);
            return writer.ToString();
        }
    }
 
    public static T Deserialize<T>(string xml)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        return (T)serializer.Deserialize(new StringReader(xml));
    }
}

Now, let’s use this in a very basic console application and look at the result:

Program.cs:

class Program
{
    static void Main(string[] args)
    {
        Person person = new Person();
        person.Name = "John Doe";
        person.Age = 27;
        person.NickNames.Add("Johnny");
        person.NickNames.Add("Doe-man");
 
        string xml = GenericSerializer.Serialize(person);
        Console.WriteLine(xml);
 
        Person deserializedPerson = GenericSerializer.Deserialize<Person>(xml);
 
        Console.WriteLine("Person name: {0}", deserializedPerson.Name);
        Console.Read();
    }
}

Output:

<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
www.w3.org/2001/XMLSchema">
  <Age>27</Age>
  <Name>John Doe</Name>
  <NickNames>
    <string>Johnny</string>
    <string>Doe-man</string>
  </NickNames>
</Person>
Person name: John Doe

Now, the serialization worked like a charm. The array of nicknames looks pretty sad though and the elements are named according to the array type. If we need to control it, such as making Name and Age attributes instead of elements and changing the nicknames structure, we can use attributes in the Person class to explain to the serialization process how to handle the data:

[XmlRoot("person")]
public class Person
{
    [XmlAttribute("age")]
    public int Age { get; set; }
 
    [XmlAttribute("name")]
    public string Name { get; set; }
 
    [XmlArray("nicks")]
    [XmlArrayItem("nick")]
    public List<string> NickNames { get; set; }
 
    public Person()
    {
        NickNames = new List<string>();
    }
}

This would give the following output:

<?xml version="1.0" encoding="utf-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
www.w3.org/2001/XMLSchema" age="27" name="John Doe">
  <nicks>
    <nick>Johnny</nick>
    <nick>Doe-man</nick>
  </nicks>
</person>

There are a bunch of attributes that can be useful when explaining how to serialize the data. Here’s some:

XmlElement
Use the property as a XML element. If used on an array the array items are serialized without a root and straight into the current parent.

[XmlElement("age")]
public int Age { get; set; }
 
//<person>
//   <age>27</age>
//</person>

XmlAttribute
Use the property as a XML attribute.

[XmlAttribute("name")]
public string Name { get; set; }
 
//<person name="John Doe" />

XmlArray
Use the property as an array and set the name of the array root. Without the XmlArrayItem attribute the content is described by its type.

[XmlArray("nicks")]
public List<string> NickNames { get; set; }
 
//  <NickNames>
//    <string>Johnny</string>
//    <string>Doe-man</string>
//  </NickNames>

XmlArrayItem
Name the items of the array to serialize. Preferably used with XmlArray. If XmlArray is not used the root will be named according to the property name and the items according to this attribute value.

[XmlArray("nicks")]
[XmlArrayItem("nick")]
public List<string> NickNames { get; set; }
 
//  <nicks>
//    <nick>Johnny</nick>
//    <nick>Doe-man</nick>
//  </nicks>

XmlIgnore
A useful attribute if your representation class contains properties that you don’t want to use in serialization/deserialization. Any property marked with this attribute will be ignored.

These are some of the basics in XML serialization in C#. I will be writing a couple of more articles on the subject where I will be more specific (such as how to skip serializing properties conditionally and how to work with inheritance in serialization).

Extra example
I just thought I’d add an extra example, as it can be handy, on what to do if you get data from someone else that you need to deserialize. What if we get an XML file that looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<catalog>
  <books>
    <book isbn="1234-5-513-234">
      <title>A Tale Of Two Cities</title>
      <author>Charles Dickens</author>
      <publishingYear>1859</publishingYear>
    </book>
    <book isbn="4433-1-982-123">
      <title>The Catcher In The Rye</title>
      <author>J. D. Salinger</author>
      <publishingYear>1951</publishingYear>
    </book>
    <book isbn="9182-3-515-143">
      <title>How The Steel Was Tempered</title>
      <author>Nikolai Ostrovsky</author>
      <publishingYear>1932</publishingYear>
    </book>
    <book isbn="1999-8-313-532">
      <title>Confucius From The Heart</title>
      <author>Yu Dan</author>
      <publishingYear>2006</publishingYear>
    </book>
  </books>
</catalog>

Well, all we have to do is create two classes, Catalog and Book, and give them the corresponding properties and attributes:

Book.cs

namespace XmlSerializationTest
{
    [XmlType("book")]
    public class Book
    {
        [XmlAttribute("isbn")]
        public string ISBN { get; set; }
 
        [XmlElement("title")]
        public string Title { get; set; }
 
        [XmlElement("author")]
        public string Author { get; set; }
 
        [XmlElement("publishingYear")]
        public int PublishingYear { get; set; }
    }
}

Catalog.cs

namespace XmlSerializationTest
{
    [XmlRoot("catalog")]
    public class Catalog
    {
        [XmlArray("books")]
        [XmlArrayItem("book")]
        public List<Book> Books { get; set; }
 
        public Catalog()
        {
            Books = new List<Book>();
        }
    }
}

This would be all you need. As I’m just making an example I saved the XML as ‘Data.xml’ in my project as an embedded resource and read it like this:

namespace XmlSerializationTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Stream stream = Assembly.GetExecutingAssembly()
                .GetManifestResourceStream("XmlSerializationTest.Data.xml");
            using (StreamReader reader = new StreamReader(stream))
            {
                string xml = reader.ReadToEnd();
                Catalog catalog = GenericSerializer.Deserialize<Catalog>(xml);
            }
 
 
            Console.Read();
        }
    }
}

I used the GenericSerializer described earlier in this article and just checked that it actually deserialized correctly, which it did. Good luck!

Using a SOAP service in .NET

In this article I’ll describe how to consume a SOAP service in a .NET application. We’ll write the service itself in PHP, but the manner in which the service is written doesn’t matter. It looks like this (I’m using the NuSoap library)

<?php
	require_once('nusoap/lib/nusoap.php');
 
	function getPeople($age)
	{
		$people = array(
			array('Name' => "Magnus Ferm", 'Age' => 27, 'Gender' => 'Male'),
			array('Name' => "Nils Pils", 'Age' => 48, 'Gender' => 'Male'),
			array('Name' => "Per Bers", 'Age' => 52, 'Gender' => 'Male'),
			array('Name' => "Inga Lundh", 'Age' => 42, 'Gender' => 'Female'),
			array('Name' => "Jessie Presley", 'Age' => 18, 'Gender' => 'Female')
			);
 
		$filteredPeople = array();
		foreach($people as $person)
		{
			if($person['Age'] < $age)
				array_push($filteredPeople, $person);
		}
		return $filteredPeople;
	}
 
	$namespace = "http://www.tempuri.org";
	$server = new soap_server();
	$server->configureWSDL("PeopleService");
	$server->wsdl->schemaTargetNamespace = $namespace;
 
	$server->wsdl->addComplexType(
		'Person',
		'complexType',
		'struct',
		'all',
		'',
		array(
			'Name' => array('name' => 'Name', 'type' => 'xsd:string'),
			'Age' => array('name' => 'Age', 'type' => 'xsd:int'),
			'Gender' => array('name' => 'Gender', 'type' => 'xsd:string')
		)
	);
 
	$server->wsdl->addComplexType(
		'PersonArray',
		'complexType',
		'array',
		'',
		'SOAP-ENC:Array',
		array(),
		array(
			array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:Person[]')
		),
		'tns:Person'
	);
 
	$server->register(
					// method name:
					'getPeople', 		 
					// parameter list:
					array('age'=>'xsd:int'), 
					// return value(s):
					array('return'=>'tns:PersonArray'),
					// namespace:
					$namespace,
					// soapaction: (use default)
					false,
					// style: rpc or document
					'rpc',
					// use: encoded or literal
					'encoded',
					// description: documentation for the method
					'Returns a list of people under the age of X');
 
	// Get our posted data if the service is being consumed
	// otherwise leave this data blank.                
	$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) 
					? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
 
	// pass our posted data (or nothing) to the soap service                    
	$server->service($POST_DATA);                
	exit();
?>

This service gives you access to a method called ‘getPeople’ which takes one parameter, max age. This is not the most useful service and will only serve as a an example.
To call this service we’ll create a new project in Visual Studio. I’ve chosen a console project and to add the service we’ll do as follows:

Right click on References and select 'Add Service Reference'

Chose 'Advanced'
Choose 'Add Web Reference'
Type the address to the service, don't forget the ?wsdl-suffix and press 'Add Reference'

Now we’ve created a connection to our webservce and we should see the following in our solution explorer:

Now we can see our service in the solution explorer

If we are going to use the service we have to add a reference in the file we’re using:

using System;
using WebServiceTest.com.morkalork.services;
 
namespace WebServiceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            PeopleService service = new PeopleService();
            var people = service.getPeople(30);
 
            foreach (Person person in people)
            {
                Console.WriteLine("Name: {0}, Age: {1}", person.Name, person.Age);
            }
 
            Console.Read();
        }
    }
}
Here we have a filtered list of people from the service