Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / C#

Consuming SOAP web services - Amazon, Google et al.

Rate me:
Please Sign up or sign in to vote.
4.77/5 (18 votes)
14 Dec 2003CPOL3 min read 80.7K   502   40   3
This article describes how to build and use static proxy classes to access a web service

Introduction

Web services are built on SOAP, an XML based protocol that establishes the form that messages between web service consumers and providers should take. Traditionally, the consuming application developer would build a SOAP message manually and send it to the server, which would subsequently respond with its answer, again formatted as a SOAP message. The requirement to understand SOAP hindered the adoption of web services. To combat this, the .NET framework can wrap a lot of complexity - to the extent that a developer doesn't have to know the underlying structure of the messages at all. In fact, visual Studio makes the web service consumption process even easier, but not everyone has access to this. Thus I decided to write an example where we just used the command line tools provided as part of the free SDK, with the additional benefit that this way, you can learn a little more about what is taking place under the hood!

The simplification which .NET provides is facilitated in the following way. The interface for a given web service is described as an XML file defined in Web Services Description Language (WSDL). The WSDL lists the methods, return types, and method parameters. It is possible to programmatically analyze this interface, and statically build a stub class in your language of choice, which wrap all of the complexity of building and transporting the underlying SOAP messages. Microsoft provide a tool, wsdl.exe, which takes a reference to a WSDL file and produces these static stubs for you.

The example below should make this clearer.

Example

I found a web service at Xmethods.NET which takes returns a fortune cookie style quote each time it is invoked. Take a look at the WSDL here. The important part is shown below, which describes the getFortune method.
XML
<operation name="getFortune">
   <input name="getFortune0Request" message="tns:getFortune0Request" />
   <output name="getFortune0Response" message="tns:getFortune0Response" />
 </operation>

Step 1: Build the proxy class

Executing the following...
C:>wsdl.exe http://adrianr.dyndns.org/Fortune/Fortune.wsdl

... results in C# file, Fortune.cs which contains a class called Fortune. Examine how the methods of this class correspond to those detailed in the WSDL file, especially the following method:

C#
public string getFortune();

Also note that the generated Fortune class inherits System.Web.Services.Protocols.SoapHttpClientProtocol. This class encapsulates the actual SOAP message generation and socket transport.

(In this instance C# was used as the language of choice to build the proxy class. The command line flag /language can be used to build a stub using VB, JS etc.)

Step 2: Compile the proxy class

Next, we have to compile the auto generated file. The file contains no entry point, and thus has to be built as a library.
C:\>csc /t:library c:\Fortune.cs

Resulting in a new file Fortune.dll.

Step 3: Test the service

The next stage is to write a simple test program.
C#
using System;
using System.IO;

class WSConsumer 
{
  public static void Main() 
  {
    Fortune f = new Fortune();
    Console.WriteLine( f.getFortune() );
  }
};

When compiling this class, we have to link to the previously created Fortune.dll.

C:\>csc WSConsumer.cs /r:Fortune.dll

Then it's a matter of running resulting WSConsumer.exe to find your fortune :)

C:\>wsconsumer
"Security is when everything is settled. When nothing can happen
 to you. Security is the denial of life."
          -- Germaine Greer (b. 1939), Australian feminist,
             writer, "The Female Eunuch"

C:\>wsconsumer
"The mode by which the inevitable comes to pass is effort."
          -- Sri da Avabhas (Adi Da Samraj)

Using FortuneCookie, Amazon, Google and Code Project Web Services

People already at CodeProject have designed tools to access the Google and Code Project web services. My example doesn't have any GUI or error checking so I'm hoping my attempt might be a little clearer. As stated, I also think that Visual Studio.NET hides the stub generation from the developer. Regardless, the addition of the Amazon and the aforementioned Fortune Cookie service are new.

The four DLL's were created and built using WSDL.exe.

12/13/2003  07:42 PM             4,608 Fortune.dll
12/13/2003  09:31 PM            13,824 LatestBrief.dll
12/13/2003  09:46 PM             6,144 GoogleSearchService.dll
12/13/2003  10:12 PM            40,960 AmazonSearchService.dll

The source code to consume these services, TestWebServices.cs, is then self explanatory. The only slight complexity is that most web services will take or return types which need further work to prepare, or obtain information from. For instance, Amazon adds the notion of a KeywordRequest object...

C#
KeywordRequest req = new KeywordRequest();
req.keyword = "Web Services";
req.page = "1";
req.type = "lite";
req.devtag = "D4HGDDVSYO30N";
req.mode = "books";
ProductInfo products  = amazon.KeywordSearchRequest( req );

... and search results from Google need extracting:

C#
GoogleSearchResult result = google.doGoogleSearch( key,  // License key
            "codeproject",  // Search term
            0,              // Start at
            10,             // Max results
            true,           // Filter
            "",             // Restrict
            true,           // SafeSearch
            "", "", "" );   // ?        

// ResultElement describes one result of the search        
foreach( ResultElement res in result.resultElements )
{
    Console.WriteLine( " " + res.title + " (" + res.cachedSize + ")" );
}
Again, it is easy to ascertain how to handle these from the auto generated stubs.

Compiling the test program involves linking against each DLL.

C:\>csc TestWebServices.cs /r:GoogleSearchService.dll 
    /r:LatestBrief.dll /r:Fortune.dll /r:AmazonSearchService.dll

And finally, running TestWebServices.exe should present you with something akin to the following. It's easy to see how these could be integrated in interesting ways.

C:\>testwebservices
Usage: TestWebServices [GoogleKey] [AmazonKey]

C:\>testwebservices <snip> <snip>
A fortune cookie:
 "Justice is always violent to the party offending, for every man
 is innocent in his own eyes."
          -- Daniel Defoe (1660-1731), English journalist,
             novelist

Code Project Latest Articles:
 Add GPIB Support to Your Desktop (Available, New)
 SheetView Control (Available, New)
 Customising Visual Studio's Code Generation Templates (Available, New)
 Customising Visual Studio's Code Generation Templates (Available, New)
 Getting the most out of IDispatch (Available, Updated)

For fun, lets query Google:
 The Code Project - Free Source Code and Tutorials (47k)
 The Code Project - Free Source Code and Tutorials (101k)
 The Code Project - The Code Project Search Bar - Free Tools (59k)
 The Code Project - Free Source Code and Tutorials (46k)
 Freesticky - Code Project Syndication (47k)
 codeproject.com (7k)
 syz.de - Links (33k)
 CodeProject (16k)
 CodingCommunity - Linkliste : Linkinfo (10k)
 CodeProject Object (Microsoft Access 2002 Visual Basic Language ...  (12k)

Amazon web service:
 eBay for Dummies (0764516426)
 Developing Java Web Services: Architecting and 
      Developing Secure Web Services Using Java (0471236403)
 .NET Web Services: Architecture and Implementation with .NET (0321113594)
 Active Directory For Dummies (0764506595)
 Executive's Guide to Web Services (0471266523)
 Loosely Coupled: The Missing Pieces of Web Services (1881378241)
 Absolute BSD: The Ultimate Guide to FreeBSD (1886411743)

</snip></snip>

For further information

Information on the four services here:

These sites were also useful:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
I'm currently living in Leeds, United Kingdom.

www.benjaminwootton.co.uk

Comments and Discussions

 
GeneralMy vote of 5 Pin
Kanasz Robert27-Sep-12 8:30
professionalKanasz Robert27-Sep-12 8:30 
GeneralDataBinder.Eval Pin
TheEagle29-Jun-06 22:06
TheEagle29-Jun-06 22:06 
Hi..

I have visual studio 2003 and I am trying to use Google Search Web Service(C#).But I got the error:

DataBinder.Eval: 'EProjects.googleapi.ResultElement' does not contain a property with the name title.

The source code of the Web Form that should display the Google Search Results:

using googleapi;
/// <summary>
/// Summary description for GoogleResults.
/// </summary>
public class GoogleResults : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.ImageButton imgPrev;
protected System.Web.UI.WebControls.ImageButton imgNext;
protected System.Web.UI.WebControls.DataList lGoogle;
public EProjects.googleapi.GoogleSearchResult gsR;
public EProjects.googleapi.GoogleSearchService gcs;

private void Page_Load(object sender, System.EventArgs e)
{
gcs=new googleapi.GoogleSearchService();
gsR=gcs.doGoogleSearch(licenceKeyString,Request.QueryString["Query"],
0, 1,true, "", true, "", "", "");
PopulatelGoogle(gsR);
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
///Required method for Designer support - do not modify
///the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void PopulatelGoogle(GoogleSearchResult gsR)
{
lGoogle.DataSource=gsR.resultElements;
lGoogle.DataBind();
}
}
}


The HTML code of the same page:

<table height="100%" width="100%">
<tr>
<td colSpan="2">
<asp:datalist id="lGoogle" runat="server">
<ItemTemplate>
<span style="font-size:17px;font-weight:bold;">
<%#DataBinder.Eval(Container.DataItem,"title")%>
</span></br>
<%#DataBinder.Eval(Container.DataItem,"snipper")%>
</br> <a href='<%#DataBinder.Eval(Container.DataItem,"URL")%>'>
<%#DataBinder.Eval(Container.DataItem,"URL")%>
</a>
</ItemTemplate>
<SeparatorTemplate>
</p>
</SeparatorTemplate>
</asp:datalist></td>
</tr>
<tr>
<td align="left"><asp:imagebutton id="imgPrev" Runat="server"></asp:imagebutton></td>
<td align="right"><asp:imagebutton id="imgNext" Runat="server"></asp:imagebutton></td>
</tr>
</table>

I tried to solve this problem for a long time but I couldnt please help.


"I am too late but i will never give up"
GeneralThis helped me out. Pin
Chris Meech16-Dec-03 4:05
Chris Meech16-Dec-03 4:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.