Posted on February 29, 2008 13:47 by swilliams

XML Web Services provide a simple way to access the API of a piece of software over the Internet. Visual Studio and .NET make it stupid easy especially. However, just because something is easy to use does not mean it is impossible to make something horrible.

First a little background information before I start to rant. The standard way of creating a web service in .NET is to create an asmx file and expose various methods with the [WebMethod] attribute:

[WebMethod]
public Person[] GetAllPeople() {
  return this.datathingy.GetPeople();
}

Let's say that the Person class looks like:

public class Person {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

.NET and IIS combine to create a web service endpoint for client applications to use. This endpoint is in an XML dialect known as WSDL and looks something like this:

<s:complextype name="Person">
    <s:sequence>
	<s:element name="Id" type="s:int" minoccurs="1" maxoccurs="1" />
	<s:element name="Name" type="s:string" minoccurs="0" maxoccurs="1" />
	<s:element name="Email" type="s:string" minoccurs="0" maxoccurs="1" />
    </s:sequence>
</s:complextype>

99% of the time, you don't have to deal with the WSDL directly though; the framework takes care of it for you by deserializing the XML into an object that can be accessed similarly to the original Person instance. To consume said web service Visual Studio again makes it very easy:

public Person[] RetrievePeople() {
	PeopleService service = new PeopleService();
	return service.GetAllPeople();
}

All in all this works wonderfully and enables you to build rich functionality out of web services.

The Bad Times happen when you deviate from this path. For example, .NET is perfectly fine with letting you return any Type as the return value of a web method. So, you can return something like a DataSet, or an XmlNode. Why is this bad? I'll let someone else field the DataSet question, but let's take a look at why returning an XmlNode is bad.

Even though .NET provides many libraries to help you parse XML, it is still a painfully dreary task. Let's say you have this kind of node:

<root language="en/us">
	<Person>
		<Id>1</Id>
		<Name>Johnny Johnson</Name>
		<Email>jj@example.com</Email>
	</Person>
</root>

That's relatively straightforward, but still requires effort on your part to turn the XmlNode into something useful:

private Person ConvertXml(XmlNode node) {
    Person p = new Person();
    p.Id = Convert.ToInt32(node.SelectSingleNode("Person/Id").Value);
    p.Name = node.SelectSingleNode("Person/Name").Value;
    p.Email = node.SelectSingleNode("Person/Email").Value;
}

Notice a few glaring problems with that? First, it assumes that there are no XML namespaces that need to be added. This is biggest flaw with SharePoint's web services, it requires you add Five XML namespaces and prefixes to run xpath queries on it. But beyond all that, the code is brittle. What happens if one of the nodes that is returned doesn't have an Email tag? Kablooey. So yes, you could add a bunch of code to check for this:

private Person ConvertXml(XmlNode node) {
    Person p = new Person();
    if (node.SelectSingleNode("Person/Id") != null) {
        try {
            p.Id = Convert.ToInt32(node.SelectSingleNode("Person/Id").Value);
        } catch { } // Oh yeah, this might not be a number...
    }
    if (node.SelectSingleNode("Person/Name") != null) {
        p.Name = node.SelectSingleNode("Person/Name").Value;
    }
    if (node.SelectSingleNode("Person/Email") != null) {
        p.Email = node.SelectSingleNode("Person/Email").Value;
    }
    return p;
}

But now you have a 14 line method that still doesn't include any namespacing that many XML documents require. Tack on another 30 lines for that. Compare this to the four liner back at the top of the page. The kicker is that it still tightly coupled with the back end server. The format of the XML returned could change radically, but since it's return type is still XmlNode, you will not encounter any issues until run time. Even more, with the last code example, you will not have any errors show up, just strange behavior that can be insanely difficult to debug.

To sum up, the whole point of XML Web Services is to make it so the consumer of the service doesn't have to do a whole lot to get remote functionality of your app.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5