Export (0) Print
Expand All
Abortable Thread Pool
The Analytic Hierarchy Process
API Test Automation in .NET
Asynchronous HttpWebRequests, Interface Implementation, and More
Bad Code? FxCop to the Rescue
Basics of .NET Internationalization
Behind the Scenes: Discover the Design Patterns You're Already Using in the .NET Framework
BigInteger, GetFiles, and More
Binary Serialization of DataSets
Building Voice User Interfaces
Can't Commit?: Volatile Resource Managers in .NET Bring Transactions to the Common Type
CLR Inside Out: Base Class Library Performance Tips and Tricks
CLR Inside Out: Ensuring .NET Framework 2.0 Compatibility
CLR Inside Out: Extending System.Diagnostics
CLR Profiler: No Code Can Hide from the Profiling API in the .NET Framework 2.0
Concurrent Affairs: Build a Richer Thread Synchronization Lock
Custom Cultures: Extend Your Code's Global Reach With New Features In The .NET Framework 2.0
Cutting Edge: Collections and Data Binding
Const in C#, Exception Filters, IWin32Window, and More
Creating a Custom Metrics Tool
DataGridView
DataSets vs. Collections
Determining .NET Assembly and Method References
Experimenting with F#
File Copy Progress, Custom Thread Pools
Finalizers, Assembly Names, MethodInfo, and More
Got Directory Services?: New Ways to Manage Active Directory using the .NET Framework 2.0
High Availability: Keep Your Code Running with the Reliability Features of the .NET Framework
How Microsoft Uses Reflection
ICustomTypeDescriptor, Part 2
ICustomTypeDescriptor, Part 1
Iterating NTFS Streams
JIT and Run: Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
Lightweight UI Test Automation with .NET
Low-Level UI Test Automation
Make Your Apps Fly with the New Enterprise Performance Tool
Managed Spy: Deliver The Power Of Spy++ To Windows Forms With Our New Tool
Memory Models: Understand the Impact of Low-Lock Techniques in Multithreaded Apps
Microsoft Java Virtual Machine Update
Microsoft .NET Framework Delivers the Platform for an Integrated, Service-Oriented Web, Part 2
Mini Dump Snapshots and the New SOS
Mutant Power: Create A Simple Mutation Testing System With The .NET Framework
NamedGZipStream, Covariance and Contravariance
.NET Internationalization Utilities
.NET Profiling: Write Profilers With Ease Using High-Level Wrapper Classes
No More Hangs: Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps
The Perfect Host: Create and Host Custom Designers with the .NET Framework 2.0
Phoenix Rising
Scheme Is Love
Security Enhancements in the .NET Framework 2.0
Sepia Tone, StringLogicalComparer, and More
Software Testing Paradoxes
Stay Alert: Use Managed Code To Generate A Secure Audit Trail
Stream Decorator, Single-Instance Apps
StringStream, Methods with Timeouts
SUPERASSERT Goes .NET
Tailor Your Application by Building a Custom Forms Designer with .NET
Test Harness Design Patterns
ThreadPoolPriority, and MethodImplAttribute
ThreadPoolWait and HandleLeakTracker
Three Vital FXCop Rules
A Tidal Wave of Change
To Confirm is Useless, to Undo Divine
Touch All the Bases: Give Your .NET App Brains and Brawn with the Intelligence of Neural Networks
Transactions for Memory
Trustworthy Software
Tune in to Channel 9
UDP Delivers: Take Total Control Of Your Networking With .NET and UDP
UI on the Fly: Use the .NET Framework to Generate and Execute Custom Controls at Run Time
Unexpected Errors in Managed Applications
Unhandled Exceptions and Tracing in the .NET Framework 2.0
Using Combinations to Improve Your Software Test Case Generation
Wandering Code: Write Mobile Agents In .NET To Roam And Interact On Your Network
What Makes Good Code Good?
XML Comments, Late-bound COM, and More
Expand Minimize

Microsoft .NET and Windows XP COM+ Integration with SOAP

 

Scott Seely
Microsoft Developer Network

October 2001

Summary: This article describes how to expose existing COM+ applications over SOAP using Microsoft Windows XP and the .NET Framework. An accompanying downloadable application will allow you to follow along with the article and perform the same actions on your own machine. (8 printed pages)

Click here to download the sample.

Contents

Introduction
Original COM+ Application
The Print Service
The Client Application
Conclusion

Introduction

Microsoft® Windows XP and Microsoft .NET are introducing a lot of great new features for the Windows platform. In this article, we explore one of them: the ability to expose existing COM+ applications over SOAP. To show how this works, we came up with the following scenario:

On a Windows XP system that has Internet Information Services (IIS) installed, a COM+ application is running that allows a user to access the photos stored in the \\My Photos directory. To take advantage of SOAP integration, the owner of the machine installs the .NET Framework and exposes the COM+ application over SOAP. Another Web Service, written in C#, provides the ability for users to send images to be printed on paper. To enable users to view, manage, and print their images, a client application is written that ties everything together in one, cohesive piece.

To help you see all of this in action, we created an application that allows you to follow along with the article and perform the same actions on your own machine. Before you continue reading, I suggest that you download the sample and install it now. To run this example, you must have Windows XP Professional configured with IIS and the .NET Framework.

Original COM+ Application

The original COM+ application is called PictureApplication. It contains one COM object, ImageRetriever. When set up correctly, this COM+ application runs under a particular user's identity. Using that identity, the application has access to the user's special folders. The COM object uses this to get access to the My Pictures folder. This object exposes the following three functions:

  • GetImageNames
    Returns the list of all image files in the My Pictures folder.
  • GetImageByName
    Given a name of an image file, this function returns the file as an array of bytes.
  • SaveImage
    Given an array of bytes and a file name, this function saves the array of bytes as a file in the My Pictures folder using the passed in file name.

To expose the object as a SOAP endpoint, the COM+ application and the .NET Framework must be installed on a Windows XP system. With those requirements met, actually exposing the object is extremely easy:

  1. From within the Component Services console, navigate to the COM+ application named PictureApplication.
  2. Right-click the PictureApplication node and select Properties.
  3. Within the PictureApplication Properties property sheet, click the Activation tab.
  4. Unlike previous versions of COM+, the Activation tab includes a group box named SOAP. To enable SOAP access to this COM+ application, just click the Uses SOAP check box and fill in a name for the SOAP VRoot. This virtual root directory will be created within IIS and will host the SOAP endpoint. The property page for this application is shown in Figure 1.

    Figure 1. The new COM+ activation property page

  5. For this particular application, the virtual root directory is named WinXPPhotos. If you are following along with the sample, use the same name so that when you uninstall the application, the virtual root will be removed for you. When you click OK or Apply, a .NET interop assembly is created for you in the %WINDOWS%\System32\COM\SOAPVRoots\WinXPPhotos directory and this directory gets mapped into IIS. A few other files are created as well:
    • Default.htm
      A more or less empty HTML file that links to default.disco.
    • Default.disco
      Lists the relative URL for the Web Services Description Language (WSDL) file. For PictureApplication, it is PictureProject.ImageRetriever.soap?WSDL.
    • Web.config
      Configuration file for the Web Service. The file contains information particular to .NET Remoting.
    • Bin\[Interop assembly]
      Contains the .NET wrapper for the COM+ application if the COM+ application is written using unmanaged code. Because the original application uses traditional COM and was built with Microsoft Visual Basic® 6.0, a file exists in this directory named PictureProject.DLL. If this component was written using managed code, it would be placed in the global assembly cache (GAC) and no files would exist in this directory.

Using these files, our application is now ready to be consumed using SOAP.

The Print Service

Another entity in all of this is the Print service. It uses ASP.NET under the hood and has one method, PrintImage, which simply takes a file as a base64-encoded array of bytes and transforms those bytes into an image suitable for framing via a printer.

The Client Application

The client application ties everything together. First, I created a C# Windows Forms application. To this application, I had to add a reference to the Print service and the PictureApplication Web Service. Because the Print service was created using ASP.NET, I added a Web Reference using the Microsoft Visual Studio® .NET integrated development environment (IDE). To do this, just go to Project \ Add Web Reference and add the Photo service. Things are a bit more difficult for the PictureApplication Web Service. When referencing a Web Service that uses .NET Remoting, you need to use the soapsuds utility. From the command line, issue the following command:

soapsuds -url:http://localhost/WinXPPhotos/PictureProject.ImageRetriever.soap?WSDL –gc

This command generates a file named PictureProject.cs, which you need to add to the project. To add the file, select Project, Add Existing File, and then PictureProject.cs. You now have references to the two Web Services in your project. Because the Visual Studio .NET IDE does not automatically add a reference to the .NET Remoting DLL, you will need to add that reference as well.

With all that in place, we just had to add a user interface to access the various services. When you first open the application, the following screen is displayed.

Figure 2. Opening screen for the client application

As you can see, you get images from the server, add images to the server, and print the current image. When you select Get Image From Server, the following dialog box appears.

Figure 3. PickImage dialog box

The PickImage dialog box sends a SOAP message to the COM+ application to request all the images on the server. The exchange itself looks like this:

Request

<SOAP-ENV:Envelope 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:i2=
"http://schemas.microsoft.com/clr/nsassem/PictureProject._ImageRetriever/PhotoClient">
    <SOAP-ENV:Body>
        <i2:GetImageNames id="ref-1">
        </i2:GetImageNames>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Response

<SOAP-ENV:Envelope 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:i2="http://schemas.microsoft.com/clr/nsassem/PictureProject.
      _ImageRetriever/PictureProject">
    <SOAP-ENV:Body>
        <i2:GetImageNamesResponse id="ref-1">
            <return href="#ref-3"/>
        </i2:GetImageNamesResponse>
        <SOAP-ENC:Array id="ref-3" SOAP-ENC:arrayType="xsd:string[26]">
            <item id="ref-4">27395356.jpg</item>
            <item id="ref-5">27395357.jpg</item>
            <item id="ref-6">27395382.jpg</item>
            <item id="ref-7">27395387.jpg</item>
            <item id="ref-8">27395401.jpg</item>
            <item id="ref-9">27395408.jpg</item>
            <item id="ref-10">fig2.bmp</item>
            <item id="ref-11">FIGURE 1-1.GIF</item>
            <item id="ref-12">FIGURE 1-6.gif</item>
            <item id="ref-13">FIGURE 10-1.gif</item>
            <item id="ref-14">FIGURE 13-1.gif</item>
            <item id="ref-15">FIGURE 13-2.gif</item>
            <item id="ref-16">FIGURE 13-3.gif</item>
            <item id="ref-17">FIGURE 13-4.gif</item>
            <item id="ref-18">FIGURE 6-1.gif</item>
            <item id="ref-19">FIGURE 9-1.gif</item>
            <item id="ref-20">FIGURE 9-2.gif</item>
            <item id="ref-21">headboard.TIF</item>
            <item id="ref-22">kinkos.GIF</item>
            <item id="ref-23">kodak.GIF</item>
            <item id="ref-24">LEAF.BMP</item>
            <item id="ref-25">msnet.GIF</item>
            <item id="ref-26">nwa.bmp</item>
            <item id="ref-27">nwa.gif</item>
            <item id="ref-28">PLUS.BMP</item>
            <item id="ref-29">soap.bmp</item>
        </SOAP-ENC:Array>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

As you can see, the application is using very basic SOAP messages to communicate back and forth. The other messages are quite a bit longer because they send complete base64-encoded images. When the user double-clicks an image name or selects an image and clicks OK, the client application sends a SOAP request back to the server, asking for the particular image. The server responds by sending the raw bits for that file. Due to some niceties with the .NET graphics library, the code just takes those raw bytes and displays the image on the form. Figure 4 shows the image displayed after one such request.

Figure 4. Picture Client displaying picture of my daughter, Angeline, and my wife, Jean

When the user selects Print Image from the main menu, the client application grabs the bytes from the image and ships it off to the Print service. The PickPrinteService dialog box, shown in Figure 5, allows the user to select a print service. Of the three shown, only the Microsoft .NET option is active. The other two, Kodak and Kinkos, are for illustrative purposes only. When the print service receives the image, it does something similar to the code just shown to draw the image to the screen. Of course, this code puts the image on paper, but it isn't much different.

Figure 5. The PickPrintService dialog box

Conclusion

This example shows how to use Windows XP and the .NET Framework to expose a picture storage COM+ application. It also demonstrates how to transfer large amounts of binary data using a Web Service. Using Windows XP and the .NET Framework, you can easily expose existing COM+ applications as SOAP endpoints. The bulk of the work involves checking a box and filling in the naming of a virtual directory from within the Component Services console. After that, using the endpoint works the same as using any other SOAP endpoint.

Show:
© 2015 Microsoft