Chapter 15. Creating Web Services with .NET

Microsoft, one of the early backers of the Web services concepts and standards, is also one of the vendors who is betting the future on the success of Web services. The .NET platform is designed from the ground up to support the efforts of Web services developers and consumers.

Creating Web Services with .NET

The conversion of almost the entire Microsoft software development toolset to create .NET applications is proof of this commitment. As of this writing, of all the tools in the Visual Studio IDE, only Visual C++ contains an option to generate traditionally compiled executables, which are called unmanaged applications.

Visual Studio .NET is a full-featured Integrated Development Environment (IDE). As such, it contains tools to create a large number of different types of Windows and Web applications. In this hour, we will look at the .NET platform and tools from a Web services developer’s point of view. You will learn

  • About the .NET architecture

  • What .NET is and how it is different

  • How to create Web services using Visual Basic

  • How to create a .NET Web service that passes parameters

Understanding the .NET Architecture

The .NET architecture is a completely new direction in software development for the Microsoft Windows platform. Microsoft has abandoned the traditional DLL approach in favor of a runtime-based system that resembles the approach Sun used when creating Java. In this section, we will look at some of the unique features of this new architecture.

Visual Studio .NET

A Web services development tool must do more than just support standards to be useful. It must facilitate the creation, deployment, scaling, and maintenance of programs written to the Web services standards. One complication that arises from comparing different Web service development tools is that no two tools have exactly the same mission. One might be a bare-boned SOAP engine, whereas another is a full-featured IDE that can produce any number of types of programs in addition to Web services.

Visual Studio .NET

One development tool might be free to download, and the other could cost hundreds of dollars. The Visual Studio .NET Integrated Development Environment (VS .NET IDE) contains so many features and software products that it seems unfair to discuss only the aspects of it that pertain to Web services. In addition to Web services projects, the VS .NET IDE allows a programmer to create a C++ program, a Web application, a Web service, a class library, a Windows control library, a Web control library, a console application, or a Windows service. In addition, every one of these projects, except for the compiled (nonmanaged) C++ project, can be created in C++, Visual Basic, or C#.

Note

Visual Studio .NET

C# is a Microsoft platform programming language that has an almost identical syntax to Java. Because it only runs on Windows platforms, it has not made many converts among Java programmers.

The thrust of this hour, however, is the use of Visual Studio to create Web services. In Hour 16, “Creating .NET Web Service Clients,” you will learn how to write a Visual Basic program that calls a Web service.

Pros and Cons of Microsoft Tools

Microsoft’s storied past has divided the developer world into two factions. One faction is composed of developers who have never given any thought to using a Microsoft programming language or product to create Web services. The other faction is composed of developers who have never considered using anything else.

Microsoft detractors offer several reasons for their attitudes—some rational and some emotional. Among the emotional reasons are memories of the wars that Microsoft has participated in with IBM over Windows, with Sun Microsystems over Java, with Netscape over browsers, with WordPerfect over word processing, and so on. The job of a technical author is not to editorialize or to take sides in these issues. Rather, our job is to evaluate product offerings based on their merits, leaving the nonquantifiable parts of the decision making process to the reader.

Ignoring the emotional reasons for not using Microsoft development tools, there have been, in our opinion, real reasons to use them and real reasons to avoid them. Among the many reasons to use them are

  • Ease of use—Until recently, few other tools in the marketplace provided as nice an IDE as Visual Studio.

  • Cost—Many developers could afford to purchase their own PC and a copy of Visual Studio. This allowed them to enhance their skill sets in the evenings.

  • Jobs—Before Java became all the rage, so many more opportunities were available for developers who knew Visual C++ and Visual Basic than for any other language.

  • Documentation—Microsoft provides reams of documentation on every one of its products.

  • Support—Microsoft answers the phone.

For these reasons, hordes of developers have become proficient with Microsoft software development. There are also valid reasons for not choosing Microsoft tools:

  • Windows architecture—Windows has been considered unstable and complicated by developers. Some of this springs from the Dynamic Link Library (DLL) architecture. A DLL is a library of function calls loaded into the memory of the computer and shared by multiple applications. Whenever a new software product is installed on a machine, it normally installs the DLL versions that it needs. As a result, the installation of a new product might cause an old product to stop working. In extreme cases, hard drives have been reformatted to get rid of DLL conflicts.

  • Over-engineered tools—Visual Basic provides so much handholding that developers sometimes felt like they were fighting with the tool in order to get certain tasks accomplished.

  • Strangely engineered tools—Some tools, like Visual C++, require the use of macros in their Windows application code. The existence of anything mysterious in a program drives software engineers crazy.

  • Unnecessary complication—Many GUI developers considered the Windows API to be a nightmare. The MFC helped this a little, but only a little.

  • Hardware and operating system monopoly—Microsoft tools produced code that only ran under Microsoft Windows on X86 machines.

  • Proprietary mindset—Many developers interpreted Microsoft’s opposition to Netscape and Java as being against open standards. The truth of this point is of little importance because the developer community believed it to be true.

This being said, Microsoft has made great strides—both with regard to technology and people’s perceptions—in the past few years. Most companies have been known to “throw sharp elbows” at the competition from time to time. In recent years, Microsoft has actively participated in countless efforts to create standards that are truly open and developer driven. The short list includes XML, SOAP, WSDL, and UDDI. On the longer list are many of the emerging specifications for dealing with Web service security, encryption, transactions, business process support, and so on.

Microsoft has also established polite relationships with former enemies. IBM and Microsoft have worked together to write an impressive number of emerging Web service specifications. Recently, Sun Microsystems joined the Web Services Interoperability Organization that Microsoft helped found.

The .NET Runtime

The .NET platform represents a radical departure from the traditional Microsoft approach to software development. In the past, Visual C++ was used to do most of the heavy lifting on Windows machines. Visual C++ is a traditional, compiled language in which machine-level instructions are emitted from the compiler. Although this option is still available in Visual Studio .NET, the preferred approach to writing applications in C++, C#, and Visual Basic is to use the features of the .NET platform. The .NET platform is organized in a way that is similar to the Java platform.

The .NET Runtime

At the top level, each programmer uses the language that she prefers (for example C#, VB.NET, or managed C++). When the code is compiled, however, it is compiled into a byte-code called Microsoft Intermediate Language (MSIL). Regardless of the language used, the MSIL code generated will be identical if the same functionality is created. This MSIL code is compiled at runtime into CPU instructions and run. Figure 15.1 shows this process.

Your code is compiled into MSIL code. At runtime, the MSIL code is interpreted into CPU instructions.

Figure 15.1. Your code is compiled into MSIL code. At runtime, the MSIL code is interpreted into CPU instructions.

Many of you might notice how similar this approach is to the Java approach. In some ways, this serves as a ratification of the Java architecture. This is good news for the development community.

Although it is useful to think of the .NET runtime as similar to the Java Virtual Machine, it would be a mistake to carry the analogy too far. .NET is composed of quite a number of features—some of them have a Java counterpart, whereas others don’t.

Common Language Runtime

Common Language Runtime

The Common Language Runtime (CLR) is a software program that can run MSIL code. Because the MSIL code is identical, regardless of the programming language used to write it, languages can interact in ways not possible before. Java applications are, by definition, written in Java. CLR applications can be written in any MSIL-emitting language. Microsoft currently provides three of these languages: C++, C#, and Visual Basic. Third-party vendors have announced their intention to create .NET versions of just about every other language that you ever worked with.

The ability to use several different languages to write Web services is more important to developers who are proficient in other languages. Microsoft has attempted to attract Java developers to .NET by releasing Visual J#, a Java syntax language that is closer to Java than C# is.

The CLR is responsible for tasks such as creating objects, making method calls, opening sockets, performing I/O, and so on. An additional feature of this framework is the theoretical possibility that you could port the CLR to another hardware platform and run it there. Some parts of .NET have been submitted for standardization to ECMA, but this doesn’t necessarily mean that other vendors will create versions of it for platforms.

The .NET Framework

Another core part of the .NET architecture is the base framework, or class library. The framework is a set of classes that enable your code to access functionality within the .NET CLR. In addition, many of the classes provide your program with utility functions such as the C-runtime library, the Visual Basic runtime library, or the Java optional downloads (formerly known as standard extensions) provide.

All the classes in the framework start with the namespace System. It contains classes for exception handling, garbage collection, and console I/O, as well as data type conversions, random number generation, and math functions. Many of these classes have a concrete implementation that is instantiated by the .NET CLR. These objects are always available to your code without having to instantiate them. Figure 15.2 shows a graphic representation of the framework.

The framework provides utility functions as well as runtime services.

Figure 15.2. The framework provides utility functions as well as runtime services.

From our point of view, the most important of these classes is the System.Web.Services class. This class is imported and used in the creation of Web services. The power of this class is what makes Web service creation so much easier with .NET than with other technologies. This class handles all the SOAP message creation and consumption as the service is communicating with a client. In addition, the client can use this same class to perform SOAP messaging tasks. Table 15.1 shows several of the important System classes.

Table 15.1. Some Critical System Classes

Class

Purpose

System.Web.Services

Provides client and server support for SOAP-based Web service

System.Timers

Timing services

System.Collections

Collections such as lists, queues, hash tables, and so on

System.Net

Support for networking

System.Threading

Multithreaded programming

System.Drawing

2D Graphics

System.Runtime Serialization

Binary and SOAP encoding

System.Security

Security services

System.Cryptography

Encryption and decryption

Namespaces and Naming Conventions

Literally hundreds of classes are built in to the .NET framework. In addition, you have the opportunity to create new functionality by extending the framework. With this many classes hanging around, naming conflicts are all but certain to occur.

Namespaces and Naming Conventions

.NET provides a solution to this problem by borrowing the concept of a namespace from other technologies such as Java and XML schema. A namespace is a unique string that is prepended to every classname. This namespace has no effect on visibility, member access, inheritance, security, or binding. The only reason that it exists is to distinguish between identical classnames.

If I create a class called Printer and store it in the namespace Xyz, the fully qualified name of the class is Xyz.Printer. If you create a class named Printer and store it in the namespace Abc, the real name of the class becomes Abc.Printer. A program could include both of these namespaces and never have a problem because the namespaces guarantee uniqueness.

The convention for user-created objects is to place your company name at the top level, followed by intermediate levels of your choice. The last name in the string will be the name that you know your object by. In this way, classes with identical names but from different companies can be distinguished.

For example, if you created a Security class, it could conflict with the System.Security class that is included with .NET. To avoid confusion, you could give your Security class a namespace prefix such as Apex.Security to make it clear which class is being referenced.

Building a Simple Web Service

ASP.NET is the recommended mechanism for implementing both Web services and Web forms in .NET. When we create a Visual Basic Web services project later in this section, you will see that you are really creating an ASP.NET application.

ASP .NET framework SDK also contains a tool to generate a proxy class that a client application can use to access the Web service.

Now that you have some understanding of the advantages of the .NET platform, let’s build a simple Web service. In the best computing book tradition, the first example will be a variation of the Hello World program. The first step in building the Web service is to create a Visual Basic solution. A VB solution is simply a collection of projects. Often, the projects in this collection work together to perform a single task or accomplish a single goal. In other cases, these projects are grouped together for convenience. In our case, we will place all the Web services that we create in the same solution for convenience. You create a solution by selecting the File menu, and then New, followed by Blank Solution. We named our solution WS24Solution.

The next step is to create a Web service by choosing New from the File menu, and then selecting Project. The dialog shown in Figure 15.3 will appear.

The New Project dialog allows you to create a Web services project.

Figure 15.3. The New Project dialog allows you to create a Web services project.

Make sure that IIS is running on your machine. Choose ASP .NET Web Service for the project type and set the location as http://localhost/WebService2.

Note

The New Project dialog allows you to create a Web services project.

It might seem odd to create an ASP .NET Web service when you really wanted to create a Visual Basic Web service. The reason for this is historical. Prior to .NET, Visual Basic programs had to use the ASP intrinsic objects to communicate via the Web.

Visual Studio will automatically create a dummy program such as the one in Listing 15.1.

Example 15.1. The Service1.asmx File

Imports System.Web.Services

<WebService(Namespace := "http://tempuri.org/")> _
Public Class Service1
    Inherits System.Web.Services.WebService
#Region " Web Services Designer Generated Code "

    Public Sub New()
        MyBase.New()

       'This call is required by the Web Services Designer.
       InitializeComponent()

       'Add your own initialization code after the InitializeComponent() call

  End Sub

  'Required by the Web Services Designer
  Private components As System.ComponentModel.IContainer

  'NOTE: The following procedure is required by the Web Services Designer
  'It can be modified using the Web Services Designer.
  'Do not modify it using the code editor.
  <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
      components = New System.ComponentModel.Container()
  End Sub

  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
      'CODEGEN: This procedure is required by the Web Services Designer
      'Do not modify it using the code editor.
      If disposing Then
          If Not (components Is Nothing) Then
              components.Dispose()
          End If
      End If
      MyBase.Dispose(disposing)
  End Sub

#End Region

    ' 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, ensure that the .asmx file is the start page
    ' and press F5.
    '
    '<WebMethod()> Public Function HelloWorld() As String
    '  HelloWorld = "Hello World"
    ' End Function

End Class

 

The first line of code declares that we intend to use one of the classes in this framework namespace in this program.

Imports System.Web.Services

The next line declares the namespace for the project. Normally, you change the namespace name to the URL for your company. It serves to uniquely identify your Web service’s name.

<WebService(Namespace := "http://tempuri.org/")> _

Next comes the declaration of the Web service class. Notice that the declaration must state that it inherits the WebService framework class.

Public Class Service1
    Inherits System.Web.Services.WebService

Visual Studio automatically generates two methods that you are instructed not to modify. By default, they are created in a region that is collapsed so that you do not see them.

 Public Sub New()
 Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

Next, a comment section is provided that contains some sample code, along with instructions on how to run it. You must uncomment this code for the rest of the example to run. The uncommented code looks like this:

 <WebMethod()> Public Function HelloWorld() As String
     HelloWorld = "Hello World"
 End Function

This code represents a very simple Web service. Web services contain no user interface because they run on the server. In order to access their functions, Visual Studio automatically generates a simple Web page for you.

You can run this example by choosing Build Solution from the Build menu, and then pressing F5.

The first thing that you will see is a screen that gives you the opportunity to run the example as shown in Figure 15.4.

Visual Studio generates a service summary for you.

Figure 15.4. Visual Studio generates a service summary for you.

If you click on the name of the operation, you will be shown another page that will let you invoke the service by clicking on a button as shown in Figure 15.5.

By clicking on the Invoke button, you can run a client that tests the operation of the Web service.

Figure 15.5. By clicking on the Invoke button, you can run a client that tests the operation of the Web service.

The result that you get back from doing this may be a little disappointing. It is shown here:

<?xml version="1.0" encoding="utf-8" ?>
  <string xmlns="http://tempuri.org/">Hello World</string>

Essentially, this is the Hello World string surrounded by enough metadata to allow it to be displayed. You can copy this result into a file called HelloWorld.xml as shown in Listing 15.2.

Example 15.2. The HelloWorld.xml File

<?xml version="1.0" encoding="utf-8" ?>
  <string xmlns="http://tempuri.org/">Hello World</string>

If you run this example in a Netscape browser, you will see the result shown in Figure 15.6.

You can display the result of running the Web service in a browser.

Figure 15.6. You can display the result of running the Web service in a browser.

The generated client is not particularly useful for anything other than verifying that the service works. Hour 16 provides several examples of more interesting clients.

Creating Your Own Web Service

Creating your own Web service is only slightly more complicated than writing any other Visual Basic subroutines or functions. The next Web service that we will create takes advantage of a special feature of Visual Basic .NET—the capability to pass values to a Web service by reference.

As you recall, when a parameter is passed by value, a copy of the parameter value is passed. When it is passed by reference, the actual location of the value is passed, allowing the called method to modify code in the original program. Because Web services are called via a wire protocol and not by passing addresses, it is clear that values cannot really be passed by reference. However, the trickery available in the .NET CLR enables Visual Basic Web services to simulate a call by reference.

We will work an example to see how this works. Create a new Web services project under the WS24 solution and call it RefService1. When the default Service1 class is created, rename it to ByRefService1 by changing the classname in the code and in the Solution Explorer window on the right, as shown in Figure 15.7.

You can rename the Web service by changing both the classname and the name in the Solution Explorer.

Figure 15.7. You can rename the Web service by changing both the classname and the name in the Solution Explorer.

Next, delete all the Hello World code out of the class and modify the code until it looks like Listing 15.3.

Example 15.3. The ByRefService1.asmx File

Imports System.Web.Services

<WebService(Namespace:="http://tempuri.org/")> _
Public Class ByRefService1
  Inherits System.Web.Services.WebService

#Region " Web Services Designer Generated Code "
#End Region
<WebMethod()> Public Function PassByRef(ByRef int1 As Integer, ByRef dateArg As Date) As String
        int1 = int1 + 300
        dateArg = dateArg.AddYears(1)
        Return "Finshed changing the parameters"
  End Function

End Class

Several things are different now. The name of the class is different, though it still inherits the System.Web.Services.WebService class.

Public Class ByRefService1

The Function is different also. In this example, two parameters are both marked with the ByRef qualifier, which means that they are to be passed by reference.

<WebMethod()> Public Function PassByRef(ByRef int1 As Integer, ByRef dateArg As Date) As String

Notice that the return value of the function is of a different type than either of the parameters. Before you can run this example from the IDE with the F5 key, you first need to alter the solution’s properties to start this project. Select the solution’s properties by right-clicking on the solution name and choosing Properties from the context menu that appears. The dialog shown in Figure 15.8 will appear.

You change the name of the startup project in the Solution Properties dialog.

Figure 15.8. You change the name of the startup project in the Solution Properties dialog.

Change the properties to use RefServices1 as the Single Startup project, and then click the OK button. Next, press the F5 key to try and run the project. When the window appears, click on the PassByRef hyperlink. A window that looks like Figure 15.9 will appear.

No automatic test page can be generated when complex parameters are passed.

Figure 15.9. No automatic test page can be generated when complex parameters are passed.

Because of the complexity of the parameters, the HTTP Get protocol cannot be used. SOAP is the only choice of protocols for this service. An example of the SOAP message needed to communicate with this Web service is listed on the page in Figure 15.10.

The Web service can be called using a SOAP message that looks like this.

Figure 15.10. The Web service can be called using a SOAP message that looks like this.

The response will look something like the one in Figure 15.11.

A SOAP message is used to make the call.

Figure 15.11. A SOAP message is used to make the call.

Note

A SOAP message is used to make the call.

Figures 15.10 and 15.11 appear at the bottom of the same window as shown in Figure 15.9.

The SOAP messages are important if you are communicating with this service via a non-.NET language. Luckily for us, we can create a .NET project that can call this Web service’s methods without having to dive into SOAP at all.

Create a client by creating a new Visual Basic Windows application. In that project, create a single form. Use the toolbox to add one button on the form named btnPassByRef. Modify the code to match Listing 15.4, choose the Project menu, and then Add Web Reference to make the association between this project and the Web service that we want to use. Figure 15.12 shows what this dialog looks like.

We must add a Web reference to the project before we can call its methods.

Figure 15.12. We must add a Web reference to the project before we can call its methods.

Note

We must add a Web reference to the project before we can call its methods.

You might have to manually enter the URL of the Web service when the dialog appears.

Now we are ready to add some code. Enter the code from Listing 15.4 into our project.

Example 15.4. The Form1.vb File

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
#End Region

Private Sub btnPassByRef_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPassByRef.Click
        Dim WS As New localhost.ByRefService1()

        MsgBox("Button Clicked")

        Dim D As Date = Now()
        Dim Int As Integer = 100
        Dim Str As String
        Str = WS.PassByRef(Int, D)
        Console.WriteLine("Return value = " & Str)
        Console.WriteLine("Integer arg = " & Int)
        Console.WriteLine("Date arg = " & D)

    End Sub
End Class

In the event handler for the button, we first declare an instance of the Web service.

     Dim WS As New localhost.ByRefService1()

Following that, we display a message box just to provide assurance that the procedure ran.

     MsgBox("Button Clicked")

We declare three local variables—a Date, an Integer, and a String.

     Dim D As Date = Now()
     Dim Int As Integer = 100
     Dim Str As String

Next, we use the handle to the Web service to make a call, passing in the Date and the Integer and getting a String return value.

     Str = WS.PassByRef(Int, D)

We then write the return value to the console.

     Console.WriteLine("Return value = " & Str)

We also write the local variables to the console.

     Console.WriteLine("Integer arg = " & Int)
     Console.WriteLine("Date arg = " & D)

The results that we get back might surprise you.

Return value = Finshed changing the parameters
Integer arg = 400
Date arg = 1/14/2004 10:18:35 PM

The return value is what you would expect. The Integer and Date parameters have been changed locally, which is what you want if you pass by reference. This is accomplished by cleverness in the .NET framework, however.

Summary

In this hour, you saw how Microsoft has positioned the .NET platform to be a Web services creation tool. You first learned about the pros and cons of using Microsoft tools. Following that, you were introduced to the features of .NET and Visual Studio that are the most important to Web services developers.

You also learned how to use the framework to create a simple application to demonstrate how Web services are created. Finally, you were shown a demonstration of how .NET can emulate the passing of parameters by reference to and from a Web service.

Q&A

Q

Is a .NET version of an application slower than an unmanaged version of the same application?

A

Yes, the runtime will always introduce some overhead. This overhead might not keep your application from performing, however, because of the speed of the hardware running it.

Q

Can .NET be used for all programs?

A

No, games and certain types of communication programs will always need to be written in compiled code.

Q

Is .NET a better platform for creating Web services or Web services clients?

A

It can be used for either. Although many products are oriented toward creating Web services, Visual Studio .NET is stronger than most in creating clients.

Workshop

The Workshop is designed to help you review what you’ve learned and begin learning how to put your knowledge into practice.

Quiz

1.

What is the purpose of the CLR?

2.

Do Visual C++ Web services perform better than Visual Basic Web services?

3.

What .NET class is the Web services workhorse?

Quiz Answers

1.

The common language runtime (CLR) is the .NET equivalent of the Java Virtual Machine. It runs interpreted code and exposed operating system objects to the program.

2.

No. All .NET Web services run the exact same bytecode. The choice of language is just for human convenience.

3.

The System.Web.Services.WebService class that is part of the .NET framework does all the heavy lifting associated with creating a Web service.

Activities

1.

Create a Web service that accepts a date parameter and tells you how old you will be on that date.

2.

Create a Web service that doubles any integer value passed in.

3.

Create a Web service that converts your name to all lowercase letters when you pass it in by reference.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset