Consuming a Web Service
The other end of this process is the consumption of the Web service, and it's just as easy to do. Using Visual Studio, we need only add a Web reference to the service to generate what's called a proxy class. A proxy class does what the name impliesit creates a code interface that acts as a front end to the remote code.Proxy classes are generated in one of two ways in Visual Studio 2005. If you add a reference to a Web project, several files are generated that describe the service and how to discover it. The proxy class is then generated dynamically at runtime. If you add a Web reference to a class library project, an actual class is generated and added to the project.For the moment, let's add a reference to a class library project. When you right-click on the project in the solution explorer and choose Add Web Reference, the dialog in Figure 10.2 appears.
Figure 10.2. The Add Web Reference dialog.
[View full size image]

Figure 10.3. The generated files for your Web reference.

Listing 10.6. The proxy class file generated for the EsteemBooster Web service
[View full width]
For the most part, this generated class looks a lot like your Web service code, only with additional attributes and extra methods to do asynchronous calls to the service. The only thing missing is the actual codethe creation and calculation of a Status object, based on a Person object.This code is generated based on the description offered by the Web Service Definition Language (WSDL). This is XML that describes the form of the XML data exchanged via the Web service. When you add a Web reference, Visual Studio checks the address you entered for this WSDL file. For Web services authored in .NET, you can simply append "?WSDL" to the end of an address to view the WSDL.
//--------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version:2.0.40607.16
//
// Changes to this file may cause incorrect behavior and will be
// lost if the code is regenerated.
// </autogenerated>
//--------------------------------------------------------------------
//
// This source code was auto-generated by Microsoft.VSDesigner, Version 2.0.40607.16.
//
namespace MyProject.Esteem {
using System.Diagnostics;
using System.Web.Services;
using System.ComponentModel;
using System.Web.Services.Protocols;
using System;
using System.Xml.Serialization;
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="EsteemBoosterSoap", Namespace="http://esteemshack/booster")]
public class EsteemBooster : System.Web.Services.Protocols.SoapHttpClientProtocol {
/// <remarks/>
public EsteemBooster() {
string urlSetting = System.Configuration.ConfigurationSettings.AppSettings["MyProject.Esteem.EsteemBooster"];
if ((urlSetting != null)) {
this.Url = string.Concat(urlSetting, ");
}
else {
this.Url = "http://localhost:28680/textbox/EsteemBooster.asmx";
}
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://esteemshack/booster/Boost", RequestNamespace="http://esteemshack/booster", ResponseNamespace="http:/
/esteemshack/booster", Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public Status Boost(Person peep) {
object[] results = this.Invoke("Boost", new object[] {
peep});
return ((Status)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginBoost(Person peep, System.AsyncCallback callback,object asyncState) {
return this.BeginInvoke("Boost", new object[] {
peep}, callback, asyncState);
}
/// <remarks/>
public Status EndBoost(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((Status)(results[0]));
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://esteemshack/booster")]
public class Person {
/// <remarks/>
public string Name;
/// <remarks/>
public int Age;
}
/// <remarks/>
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://esteemshack/booster")]
public class Status {
/// <remarks/>
public string Message;
/// <remarks/>
public int Dollars;
}
}
Listing 10.7. A page that calls our Web service
C#[View full width]
VB.NET
<%@ Page Language="C#" %>
<script runat="server">
void LinkButton1_Click(object sender, EventArgs e)
{
Esteem.Person peep = new Esteem.Person();
peep.Name = NameTextBox.Text;
peep.Age = Convert.ToInt32(AgeTextBox.Text);
Esteem.EsteemBooster booster = new Esteem.EsteemBooster();
Esteem.Status status = booster.Boost(peep);
ResultLabel.Text = "Message: " + status.Message + " - Dollars: " + status.Dollars.ToString("c");
}
</script>
<html>
<body>
<form id="form1" runat="server">
Name: <asp:TextBox ID="NameTextBox" Runat="server" /><br />
Age: <asp:TextBox ID="AgeTextBox" Runat="Server" /><br />
<asp:LinkButton ID="LinkButton1" Runat="server" OnClick="LinkButton1_Click">GetMessage</asp:LinkButton><br />
<asp:Label ID="ResultLabel" Runat="Server" />
</form>
</body>
</html>
<%@ Page Language="VB" %>
<script runat="server">
Sub LinkButton1_Click(sender As Object, e As EventArgs)
Dim peep As New Esteem.Person()
peep.Name = NameTextBox.Text
peep.Age = Convert.ToInt32(AgeTextBox.Text)
Dim booster As New Esteem.EsteemBooster()
Dim status As Esteem.Status = booster.Boost(peep)
ResultLabel.Text = "Message: " + status.Message + _
" - Dollars: " + status.Dollars.ToString("c")
End Sub</script>
<html>
... (same as C# version
</html>
Figure 10.4. The calling page in action.
