< C++ .NET and Using ADO.NET 5 | Main | Web Service 2 >


 

 

Building a Web Service 1

 

 

What we have in this page?

  1. What Are Web Services?

  2. A Web Service Scenario

  3. Web Services and the Future

  4. Web Service Architecture

  5. Data Formats and Protocols

  6. What Is SOAP?

  7. Web Service Description

  8. Web Service Discovery

  9. The Web Services Namespaces

  10. WebService Members

  11. Creating a Simple Web Service

-----------Next-----------------------------

  1. Using the Web Service from a Browser

  2. Using the Web Service from Code

  3. If You’re Not Using Visual Studio .NET

  4. A Very Quick Reference

In this module, you will learn how to:

 

  1. What Web services are.

  2. How Web services work.

  3. How to create a simple Web service.

  4. How to use a Web service from a browser.

Web services are an exciting feature of Microsoft .NET that make writing distributed applications much easier than before. They will change the way Web-based applications are written, and this module will show you how to get started.

 

What Are Web Services?

 

Web services are a new feature of the .NET Framework that lets client code access software components across networks using standard protocols such as SMTP and HTTP. Over the past few years, Microsoft Windows programmers have become used to COM and its role in producing software components. COM allows programmers to produce self-contained, language-independent components that can be built together into systems and used to form the basis of flexible distributed applications. Other component systems are also in widespread use, such as CORBA and Java RMI. Although COM is very useful, it has some shortcomings. First, writing COM components can be difficult because the programmer needs a wealth of arcane knowledge to write them. Second, COM uses a proprietary binary protocol to communicate between components running remotely, which makes it hard to use COM components anywhere outside of a pure Microsoft environment. Integrating a COM system with components that use CORBA or Java RMI is not at all simple. Web services help in two ways. First, you don’t need much specialized knowledge to write Web services, and it’s often very easy to provide a Web service interface to existing code. Second, Web services use standard Internet data formats and protocols for communication, so it’s a lot easier to build heterogeneous distributed systems. If you want to talk to some Windows-based components written in C++ from a remote client written in Java, you’re going to have a much easier time if you use Web services.

 

A Web Service Scenario

 

Here’s a simple scenario to show you how Web services can make the development of distributed services much easier. Imagine that on one page of your Web site, you need to present some data on currency exchange rates. How do you get up-to-date exchange rate data? In the past, you might have had to use a proprietary online service to access the data or even extract the data from HTML scraped off the appropriate Web page. If the bank provides the appropriate Web service, you can simply make a call to the remote method, passing in the currency details and getting back the exchange rate. The Web service acts as a remote procedure call (RPC), allowing you to call a function exposed by a remote Web server. The use of standard Web protocols irons out any computer or language dependencies. So you could access the service from client code written in anything from VBScript to C++.

 

Web Services and the Future

 

Web services provide a way to move toward a service-based computing model. As the world becomes more and more interconnected, it will become increasingly common to make use of Web services to build distributed applications. This might happen on many scales, from the micro to the macro. At the micro level, a programmer could use a Web service to provide a small parcel of functionality to his or her application. Someone writing a word-processing program might use Web services to provide access to specialized spelling checkers, or the writer of a spreadsheet might use Web services to give access to financial information. On the macro scale, entire applications could be exposed as Web services so that users could subscribe to software rather than buy it. In the future, it might be possible to pay Microsoft to subscribe to Microsoft Office rather than buy it. Nothing would be installed on your computer, and every time you wanted to write a document, you would connect to the remote Office service.

 

Web Service Architecture

 

Several pieces of infrastructure are needed to make Web services work, such as:

 

 

Let’s look at this infrastructure in more detail.

 

Data Formats and Protocols

 

One of the major advantages of the Web service model over Component Object Model (COM) and Common Object Request Broker Architecture (CORBA) is the use of standard data formats and protocols over proprietary offerings. Clients can communicate with Web services in the following three ways:

 

 

The first two methods use HTTP in a way that will be familiar to anyone who has written code to talk to a Web server. The use of the HTTP GET command (which adds request data to the end of the URL sent to the server) and the HTTP POST command (which passes data in the body of the HTTP message) means that you can talk to Web services from almost any language. The third method uses the SOAP protocol that is being developed by Microsoft, IBM, and several other authorities. The advantage of SOAP over HTTP is that it enables clients and servers to exchange more highly structured information than is possible with the HTTP commands.

 

What Is SOAP?

 

SOAP provides a way to call methods using XML and HTTP. The details of the method you want to call and any arguments you need to supply are formatted as an XML SOAP packet. The server parses the contents of the packet, makes the call, and sends back a reply packet, which is also in XML. SOAP gives you, in effect, an XML-based and HTTP-based RPC mechanism. SOAP relies on Worldwide Web Consortium (W3C) schemas to define the content of SOAP packets, and the use of schemas makes it possible to define and pass over structured data. SOAP isn’t a Microsoft invention, although Microsoft gives a lot of input to the committee that is defining the SOAP standard. There are SOAP bindings to many languages, and a growing number of applications are using SOAP to provide language-independent and platform-independent access to services. Binary protocols such as DCOM and CORBA often find it hard to work through firewalls, but SOAP is much easier to work with in normal commercial distributed environments because it uses HTTP to send and receive data. All three communication methods use HTTP as the transport mechanism, which means that Web services integrate very well with existing Web-based solutions.

 

Web Service Description

 

Clients need to be able to obtain a description of how to interact with a Web service, such as the name of the service and what arguments it requires. Anyone who has worked with COM will be familiar with the idea of the COM type library, which contains a description of a COM object, its interfaces, and the methods they support. The Web Service Description Language (WSDL) provides the equivalent of the type library in the .NET Framework. WSDL describes the methods exposed by a Web service and the in and out parameters they require, and as you might expect by now, it provides the information using XML. The format of WSDL files is quite complex, and because of the tools provided for you in Microsoft Visual Studio .NET, you won’t need to work with it directly, so we won’t mention it further.

 

Web Service Discovery

 

You might want to advertise the Web services that your server supports so that clients can find your service from elsewhere on the Web. DISCO (Discovery of Web Services) is a SOAP-based protocol that defines a format for description data, along with a protocol for retrieving the data. If you want to advertise your Web services, you post DISCO files on your server. Clients can use these files to navigate to the appropriate WSDL files that describe the Web services in detail. You can choose to advertise your services by static or dynamic advertising. Static advertising makes use of DISCO files that point to WSDL documents.

<?xml version="1.0"?>

<disco:discovery

    xmlns:disco="http://schemas.xmlsoap.org/disco"

    xmlns:scl="http://schemas.xmlsoap.org/disco/scl">

    <scl:contractRef ref="http://myServer/myService.asmx?WSDL"/>

    <scl:discoveryRef ref="http://someotherServer/serviceDir.disco"/>

</disco:discovery>

DISCO documents always contain a discovery element as the root and define the disco namespace (which is used to tag the discovery element) and the scl namespace. The scl namespace is used to tag the contractRef elements that point to WSDL files and to tag discoveryRef elements that point to DISCO files on linked sites. Dynamic advertising means that all Web services under a URL will be advertised automatically if you include a dynamic discovery file in the directory. Dynamic discovery files look like this:

<?xml version="1.0"?>

<dynamicDiscovery xmlns:disco="urn://schemas-dynamic:disco.2000-03-17"/>

If you place this file in the root directory of a Web server, all Web services under the root will be automatically advertised. However, you can use exclude elements to omit some directories from the search path, like this:

<?xml version="1.0"?>

<dynamicDiscovery xmlns:disco="urn://schemas-dynamic:disco.2000-03-17">

    <exclude path="_vti_cnf" />

</dynamicDiscovery>

The exclude element can be used to speed up the search by omitting directories that don’t need to be searched. It can also be used to hide Web services that aren’t publicly available. If you create Web services using Visual Studio .NET, you’ll get a dynamic discovery file created for you.

 

 

 

 

The Web Services Namespaces

 

Web services are supported by several namespaces in the .NET Framework, as listed in the following table.

 

Namespace

Description

System::Web::Services

Contains classes used to build and use Web services.

System::Web::Services::Configuration

Contains classes that configure how Web services run.

System::Web::Services::Description

Contains classes that let you describe Web services using WSDL.

System::Web::Services::Discovery

Contains classes that let client code locate Web services elsewhere on the Web.

System::Web::Services::Protocols

Contains classes that define the protocols used to transmit data in Web services.

 

Table 1

 

The System::Web::Services namespace contains the classes that you use to create and use Web services. It isn’t a large namespace, and the three main classes are listed in the following table.

 

Class

Description

WebMethodAttribute

An attribute that marks a method as callable from remote Web clients.

WebService

An optional base class used to build Web services.

WebServiceAttribute

An attribute used to add additional information to a class that implements a Web service.

WebServiceBindingAttribute

Declares a binding that defines one or more XML Web service methods. This class cannot be inherited.

 

Table 2

 

Web services will often derive from WebService class, but doing so is necessary only if you want access to the common Microsoft ASP.NET objects, as listed in the following table.

 

WebService Members

 

The WebService class defines the optional base class for XML Web services, which provides direct access to common ASP.NET objects, such as application and session state. The following tables list the members exposed by the WebService type.

 

Public Constructors

Symbol

Public method

Name

Description

WebService

Initializes a new instance of the WebService class.

 

Table 3

 

Public Properties

Symbol

Public property

Name

Description

Application

Gets the application object for the current HTTP request.

Container

Gets the container for the component. (Inherited from MarshalByValueComponent.)

Context

Gets the ASP.NET HttpContext for the current request, which encapsulates all HTTP-specific context used by the HTTP server to process Web requests.

DesignMode

Gets a value indicating whether the component is currently in design mode. (Inherited from MarshalByValueComponent.)

Server

Gets the HttpServerUtility for the current request.

Session

Gets the HttpSessionState instance for the current request.

Site

Gets or sets the site of the component. (Inherited from MarshalByValueComponent.)

SoapVersion

Gets the version of the SOAP protocol used to make the SOAP request to the XML Web service.

User

Gets the ASP.NET server User object. Can be used to authenticate whether a user is authorized to execute the request.

 

Table 4

 

Protected Properties

Symbol

Protected property

Name

Description

Events

Gets the list of event handlers that are attached to this component. (Inherited from MarshalByValueComponent.)

 

Table 5

 

Public Methods

Symbol

Public method

Name

Description

Dispose

Overloaded. Releases the resources used by the MarshalByValueComponent. (Inherited from MarshalByValueComponent.)

Equals

Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

GetHashCode

Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

GetService

Gets the implementer of the IServiceProvider. (Inherited from MarshalByValueComponent.)

GetType

Gets the Type of the current instance. (Inherited from Object.)

ReferenceEquals

Determines whether the specified Object instances are the same instance. (Inherited from Object.)

ToString

Returns a String containing the name of the Component, if any. This method should not be overridden. (Inherited from MarshalByValueComponent.)

 

Table 6

 

Protected Methods

Symbol

Protected method

Name

Description

Dispose

Overloaded. Releases the resources used by the MarshalByValueComponent. (Inherited from MarshalByValueComponent.)

Finalize

[To be supplied.] (Inherited from MarshalByValueComponent.)

MemberwiseClone

Creates a shallow copy of the current Object. (Inherited from Object.)

 

Table 7

 

Public Events

Symbol

Public event

Name

Description

Disposed

Adds an event handler to listen to the Disposed event on the component. (Inherited from MarshalByValueComponent.)

 

Table 8

 

If you don’t need access to these properties, you don’t need to derive a class from WebService.

 

Creating a Simple Web Service

 

Because you might want to expose C++ code as Web services, Visual Studio .NET contains tools to help you build and deploy Web services.

To create and use the Web services described in this module, you will need to have Microsoft Internet Information Services (IIS) running on your machine. We will try this on Windows XP Pro SP2. You can check the IIS service in the Services snap-in shown below.

 

Checking the Microsoft Internet Information Services (IIS) service using mmc snap in

 

If you computer don’t has the IIS service you need to install the component using the Add and Remove Programs (Add/Remove Windows Component) that can be accessed from Control Panel.

 

Add or remove IIS using Add or Remove program - Add/Remove Windows Components

------------------------------------------------------------------------------

------------------------------------------------------------------------------

Adding IIS using Windows Components Wizard

 

It’s also possible to write a Web service and then deploy it on another server, but doing so is outside the scope of this book. This exercise will show you how to create and deploy a simple service that implements methods to convert temperatures between Fahrenheit and Celsius.

 

1.      Create a new CLR project, and make sure that it’s an ASP.NET Web service project. Name it Converter.

 

Creatinf a new CLR project, an ASP.NET Web service project named Converter

 

2.      The following is the project environment.

 

ASP.NET Web service project environment of the Visual C++ 2005

 

3.      When you look at the project details, you’ll find an .asmx file as well as the more familiar C++ source files. The .asmx file contains details that tell the Web server which class contains the implementation of the Web service. Open the file, and take a look at the contents.

<%@ WebService Class=Converter.ConverterClass %>

 

The default .asmx file content

 

The single line tells the Web server that the Converter Web service is implemented by Converter.ConverterClass, which indicates the class named ConverterClass in the Converter namespace. If you open the ConverterClass.h file, you’ll see the class and namespace defined there. The sample class in the Converter namespace currently has one method named HelloWorld, which shows you how to add methods to a WebService class.

 

4.      You can use HelloWorld to test a Web service, but let’s replace the function with a real one. Edit the class definition in ConverterClass.h to add the two conversion functions, making sure that you remove the dummy HelloWorld function. Notice also how we’ve added the WebService attribute to the class.

[WebService(

   Namespace="http://VCSBS/WebServices/",

   Description="A Web service for converting "

         "temperatures between Fahrenheit and Celsius")]

...

...

...

 

public ref class ConverterClass : public System::Web::Services::WebService

{

         // Constructor, Dispose, and Component-related code not shown

         public:

               [WebMethod(Description="Converts temperatures from Fahrenheit to Celsius")]

               double ConvertF2C(double dFahrenheit);

               [WebMethod(Description="Converts temperatures from Celsius to Fahrenheit")]

               double ConvertC2F(double dCelsius);

 

...

...

A complete code is shown below. The Hello World part has been commented out.

 

 

 

 

// ConverterClass.h

 

#pragma once

 

using namespace System;

using namespace System::Web;

using namespace System::Web::Services;

 

namespace Converter {

      [WebService(

            Namespace="http://VCSBS/WebServices/",

            Description="A Web service for converting "

            "temperatures between Fahrenheit and Celsius")]

 

      /// [WebServiceBinding(ConformsTo=WsiProfiles::BasicProfile1_1,EmitConformanceClaims = true)]

      /// WARNING: If you change the name of this class, you will need to change the

      ///          'Resource File Name' property for the managed resource compiler tool

      ///          associated with all .resx files this class depends on.  Otherwise,

      ///          the designers will not be able to interact properly with localized

      ///          resources associated with this form.

    public ref class ConverterClass : public System::Web::Services::WebService

 {

      // Constructor, Dispose, and Component-related code not shown

      public:

            [WebMethod(Description="Converts temperatures from Fahrenheit to Celsius")]

            double ConvertF2C(double dFahrenheit);

            [WebMethod(Description="Converts temperatures from Celsius to Fahrenheit")]

            double ConvertC2F(double dCelsius);

 

    public:

            ConverterClass()

            {

                  InitializeComponent();

                  //

                  //TODO: Add the constructor code here

                  //

            }

      protected:

            /// <summary>

            /// Clean up any resources being used.

            /// </summary>

            ~ConverterClass()

            {

                  if (components)

                  {

                        delete components;

                  }

            }

 

      private:

            /// <summary>

            /// Required designer variable.

            /// </summary>

            System::ComponentModel::Container ^components;

 

#pragma region Windows Form Designer generated code

            /// <summary>

            /// Required method for Designer support - do not modify

            /// the contents of this method with the code editor.

            /// </summary>

            void InitializeComponent()

            {

            }

#pragma endregion

 

            // WEB SERVICE EXAMPLE

            // The HelloWorld() example service returns the string "Hello, World!".

            // To test this web service, ensure that the .asmx file in the deployment path is

            // set as your Debug HTTP URL, in project properties.

            // and press F5.

 

      public:

        // [System::Web::Services::WebMethod]

        // String ^HelloWorld();

 

        // TODO: Add the methods of your Web Service here

      };

}

The Description of the WebServiceAttribute has been declared with string literals on two separate lines. If the C++ preprocessor sees two adjacent string literals, it will concatenate them, which provides an easy way to split long strings over more than one line. Web services are a very good advertisement for the use of attributes, and you can see here how attributes are used to add the necessary metadata to ordinary C++ classes and members. The WebService attribute provides a description and an XML namespace for the service that is used to distinguish it from other services on the Web that might have the same name. You can also use this attribute to supply a name if you want the service name to be different from that of the namespace and class. The WebMethod attribute shows that these two methods are exposed by the Web service.

 

5.      Implement the ConvertC2F and ConvertF2C functions by editing the ConverterClass.cpp file so that it looks like this:

double ConverterClass::ConvertF2C(double dFahrenheit)

{

     return ((dFahrenheit - 32) * 5) / 9.0;

}

 

double ConverterClass::ConvertC2F(double dCelsius)

{

     return (9/5.0 * dCelsius) + 32;

}

 

A complete code is shown below.

// Converter.cpp : main project file.

 

#include "stdafx.h"

#include "ConverterClass.h"

#include "Global.asax.h"

 

namespace Converter {

 

   // WEB SERVICE EXAMPLE

   // The HelloWorld() example service returns the string "Hello, World!".

   // To test this web service, ensure that the .asmx file in the deployment path is

   // set as your Debug HTTP URL, in project properties.

   // and press F5.

   

    double ConverterClass::ConvertF2C(double dFahrenheit)

    {

        return ((dFahrenheit - 32) * 5) / 9.0;

    }

 

    double ConverterClass::ConvertC2F(double dCelsius)

    {

        return (9/5.0 * dCelsius) + 32;

    }

}

6.      Build the project. The code will compile, and the Web service will automatically deploy on your Web server. You can verify that the service has been installed by looking at the Web server’s Inetpub\wwwroot directory, where you should see a virtual directory with the same name as the project.

 

Web service automatically deploy on the Web server

 

And that all. Some Web services will obviously be more complicated, but creating a Web service can be as simple as adding some attributes to a class.

 

 

Part 1 | Part 2

 

 


< C++ .NET and Using ADO.NET 5 | Main | Web Service 2 >