Reading WSDL Documents with .NET



Reading WSDL Documents with .NET

It's easy to read and write WSDL documents with the .NET Framework. Specifically, the namespace System.Web.Services.Description contains a complete API for doing just that. The automatic generation of WSDL (*.asmx?WSDL) and the consumption of WSDL documents by wsdl.exe both use this API.

Providing Documentation to Humans

WSDL is a useful tool for describing the semantics and syntax of a Web service. However, it's a complicated XML structure that isn't well suited to humans. Furthermore, it doesn't allow you to completely express everything about your service. Therefore, it is still important to provide human-readable documentation for your Web service, and the easiest and most popular way to do this is with a series of HTML pages.

To illustrate how easy it can be, I'll show you a simple Windows application that will take the name of a WSDL file, and display the various properties of that file in a tree control. Figure shows this application running within Visual Studio .NET.

1. The Running Application

graphics/10fig01.gif

To begin with, we'll create an XmlSerializer based on the Service Description, which represents the root of a WSDL document. In addition, we'll deserialize the WSDL file into the ServiceDescription class.

XmlSerializer ser = new XmlSerializer( typeof(ServiceDescription) ); 
FileStream file = new FileStream( txtWSDL.Text, FileMode.Open );
ServiceDescription wsdl = (ServiceDescription)ser.Deserialize( file );
file.Close();

This code is deserializing the XML into a file that the txtWSDL textbox defines.

Next, we can create a set of tree nodes that lists all of the messages found in the WSDL document. (I'm ignoring the <types>section.)

TreeNode messagesNode = new TreeNode( "messages" ); 
foreach( System.Web.Services.Description.Message m in wsdl.Messages )
{
     TreeNode n = new TreeNode( m.Name );
     messagesNode.Nodes.Add( n );
}
treeWSDL.Nodes.Add( messagesNode );

Notice that we can look through the entire collection of messages that the WSDL defines this way. Now, let's do the same basic thing for each of the other major sections of the WSDL:

TreeNode pNode = new TreeNode( "portTypes" ); 
foreach( System.Web.Services.Description.PortType p in wsdl.PortTypes )
{
     TreeNode n = new TreeNode( p.Name );
     pNode.Nodes.Add( n );
}
treeWSDL.Nodes.Add( pNode );
TreeNode bNode = new TreeNode( "bindings" );
foreach( System.Web.Services.Description.Binding b in wsdl.Bindings )
{
     TreeNode n = new TreeNode( b.Name );
     foreach(
            System.Web.Services.Description.OperationBinding o
            in b.Operations )
     {
          TreeNode n1 = new TreeNode( o.Name );
          n.Nodes.Add( n1 );
     }
bNode.Nodes.Add( n );
}
treeWSDL.Nodes.Add( bNode );

TreeNode services = new TreeNode( "services" );
foreach( Service s in wsdl.Services )
{
          TreeNode ports = new TreeNode( "ports" );
          foreach( Port p in s.Ports )
          {
          TreeNode n = new TreeNode(
                 p.Name + " — " + p.Binding.ToString() );
          ports.Nodes.Add( n );
          }
          services.Nodes.Add( ports );
}
treeWSDL.Nodes.Add( services );

Notice that we have processed each of the types. Because some types also contain subtypes (such as the way in which services also contain types), we can loop through those as well, all using the foreach statement.