To read the article online, visit http://www.4GuysFromRolla.com/articles/101503-1.aspx

An Extensive Examination of Web Services: Part 2

By Scott Mitchell


Introduction


In the previous installment of this article series, we examined the standards and technologies that make up Web services. We discussed how Web services provide a distributed architecture by which one computer can invoke a method on another computer over some network, such as the Internet. This interaction is made possible by both the client and server agreeing on a set of standards and protocols for message delivery and message serialization. To briefly recap, Web services communicate over the Internet using the HTTP protocol. Messages are formatted according to the SOAP specification. SOAP messages are plain-text and XML formatted.

In the previous installment we focused solely on examining Web services from 30,000 feet, and did not bother to actually implement a Web service provider and consumer. In this article, we'll look at how to build a Web service using Visual Studio .NET. As we'll see, Visual Studio .NET makes it incredibly easy to build a Web service.

Building a Web Service with Visual Studio .NET


Creating a Web service is Visual Studio .NET is so easy it is almost frightening. Start by creating a new ASP.NET Web Service project in the programming language of your choice. (For this article series, I'll be focusing on C#, and will point out any differences between VB.NET and C# that are germane.) As the screenshot to the right shows, when adding a new Web service project you are asked to specify a location in the form of a folder on a Web server. Since Web services are accessed via HTTP, Web services typically are implemented as a file on a Web site. To invoke the Web service, a client will make an HTTP request to the Web service's URL, passing in the SOAP message in the HTTP POST body. For this reason, an ASP.NET Web Service project is created as a new folder on a Web server. The Web service(s) we create in this project will be files located in this folder.

If you want to follow along, specify the location for your Web service project as http://localhost/MyFirstWS and click the OK button. Upon doing so, a new virtual directory - MyFirstWS - will be created on your computer's Web server. For Web service projects, VS.NET creates a few files, which you can see in the Solution Explorer screenshot shown below. These files automatically created for you are:

  • AssemblyInfo.cs - contains metadata information about the assembly created by the Web service.
  • Global.asax - the place where you can supply event handlers for the application and session-level events.
  • Service1.asmx - a Web service file
  • Web.config - an XML-formatted configuration file

Don't worry about AssemblyInfo.cs or Global.asax, we won't be discussing those at all throughout this article series. The Service1.asmx file is a Web service file. Note that Web services in the .NET Framework have an .asmx extension. The Web.config file contains configuration information for the ASP.NET application. As we'll see in future installments of this article series, there is a special section in the Web.config file for Web service-related settings.

Examining the Web Service File


Service1.asmx is the default Web service file created by Visual Studio .NET when creating a new project. You can create additional Web service files by right-clicking on the solution name in the Solution Explorer and choosing to Add a New Item of type Web Service. Web service files, unlike ASP.NET pages, don't have any visual component to them; rather, they are comprised of just code. To get to the source code for Service1.asmx, right-click on Service1.asmx in the Solution Explorer and choose the View Code option.

Whenever you create a new Web service file, VS.NET automatically adds some default code for you to help get you started. This code, with some sections snipped for brevity, is shown below:

namespace MyFirstWS
{
   public class Service1 : System.Web.Services.WebService
   {
      // WEB SERVICE EXAMPLE
      // The HelloWorld() example service returns the string Hello World
      // To build, uncomment the following lines then save and build the project
      // To test this web service, press F5

//      [WebMethod]
//      public string HelloWorld()
//      {
//         return "Hello World";
//      }
   }
}

The first thing to note is that a Web service is merely a class that is derived from the System.Web.Services.WebService class. Recall from the first installment of this article series that a Web service is comprised of a number of methods. To add a method to the Web service, you simply need to create a public method in the class that is predicated with the [WebMethod] attribute - it's that simple.

Let's create a Web service that has a single method called add(), that takes in two integer parameters and returns their sum. To add this method, we'd simply add to the Service1 class the following code:

// C# code...
[WebMethod]
public int add(int x, int y)
{
   return x + y;
}


'VB.NET code
<WebMethod> _
Public Function add(x as Integer, y as Integer) as Integer
  Return x + y
End Function

(Note that attributes in VB.NET use less than and greater than as opposed to the square brackets. Also, since VB.NET is line-break sensitive, if you want the <WebMethod> attribute to appear on the line before the function definition, you need to use a line continuation character (_) after the attribute.)

Once we have added this function, we can build the Web service by going to the Build menu and choosing Build Solution. This will compile the class into an assembly (a DLL file) and will store that assembly in the Web application's /bin directory. At this point, we can test our Web service through the browser interface by visiting the Web service URL. Fire up your browser of choice and head on over to http://localhost/MyFirstWS/Service1.asmx.

When visiting a Web service through the browser, the ASP.NET engine displays an informational page about the Web service and its methods. As the screenshot below shows, when first visiting the page you are displayed a list of the methods as well as a link to the Service Description. If you'll recall, in the previous installment we briefly discussed WSDL, which is a standard for formally defining a Web service. We'll dive into WSDL in much greater detail in future installments, but for now realize that by clicking the Service Description link you'll be taken to the Web service's WSDL document.

By clicking on a method name (add, in this case), you can see information about the particular method. This information spells out the format of the SOAP request message it expects as well as the format of the SOAP response message it will send, and also provides a Web Form for testing out the Web service. The SOAP request message expected by the Web service is shown below. Recall that this is the message the client will pass to the Web service to indicate that it wants to invoke the add() method and with what particular input parameters:

POST /MyFirstWS/Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/add"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope namespaces>
  <soap:Body>
    <add xmlns="http://tempuri.org/">
      <x>int</x>
      <y>int</y>
    </add>
  </soap:Body>
</soap:Envelope>

Note that the SOAP Body will need to contain first an element named <add>. Then, the <add> method contains two children elements, <x> and <y>, whose text contents will be the values of the methods input parameters. The SOAP response message, which is passed back from the Web service to the invoking client, specifies the return value of the add() method:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope namespaces>
  <soap:Body>
    <addResponse xmlns="http://tempuri.org/">
      <addResult>int</addResult>
    </addResponse>
  </soap:Body>
</soap:Envelope>

As we will see in future installments, it is the WSDL document that spells out precisely the format of SOAP messages the server will accept and will return. It is the client's responsibility to send a properly formatted message to initiate the Web service method call.

Imagine that a client wanted to utilize the Web service method we just created to add 7 and 3. The following diagram illlustrates the request and response messages that would be passed back and forth. Note that the server's response contains the output of the method call - the integer value 10.

Passing in and Returning Complex Objects to a Web Service


In our previous examples we saw how to pass in a simple, scalar value into a Web service (namely, an integer). Web services can also accept and return complex parameters, such as arrays and objects with both complex and simple properties. For example, imagine that we were building a Web service for a credit card processing company, and needed to create a Web service which merchants could invoke that would accept credit card information and a charge amount and then debit the account accordingly. We could define a CreditCardInfo class in the same file as our Web service. This class could contain the properties that define the information for a credit card, such as the number, the expiration month/year, and other pertinent info.

Next, we'd create our Web service that would accept two input parameters: a CreditCardInfo parameter and a float parameter (the amount to charge to the credit card). The method could then return a Boolean, indicating if the charge was successfully made or not. The following shows the Web service file with the added CreditCardInfo class and the added ProcessCreditCard() method in the Web service class:

namespace MyFirstWS
{
   public class Service1 : System.Web.Services.WebService
   {
     ...
     
     [WebMethod]
     public bool ProcessCreditCard(CreditCardInfo ccInfo, float amount)
     {
        ...
     }
   }
   
   // Create the CreditCardInfo class...
   public class CreditCardInfo
   {
     public string Number;
     public int ExpMonth;
     public int ExpYear;
   }
}

Complex input and return values are appropriately serialized in the request and response SOAP messages. For example, the SOAP request message for the ProcessCreditCard() method would look like:

POST /MyFirstWS/Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/ProcessCreditCard"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope namespaces>
  <soap:Body>
    <ProcessCreditCard xmlns="http://tempuri.org/">
      <ccInfo>
        <Number>string</Number>
        <ExpMonth>int</ExpMonth>
        <ExpYear>int</ExpYear>
      </ccInfo>
      <amount>float</amount>
    </ProcessCreditCard>
  </soap:Body>
</soap:Envelope>

Conclusion


In this article we looked at how to build a Web service with Visual Studio .NET. The process is simple enough - you just create a Web service project and add public methods to the class that are marked with the [WebMethod] attribute. These methods can accept and return both simple scalar inputs as well as complex objects. Web services can also be easily created without using Visual Studio .NET. For more information on creating Web services with any old text editor, be sure to read an earlier article of mine, Creating and Consuming a Web Service.

Happy Programming!

  • By Scott Mitchell


  • Article Information
    Article Title: ASP.NET.An Extensive Examination of Web Services, Part 2
    Article Author: Scott Mitchell
    Published Date: October 15, 2003
    Article URL: http://www.4GuysFromRolla.com/articles/101503-1.aspx


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers