Chapter 7. Interoperability

In This Chapter

The Windows Communication Foundation (WCF) provides a unified API for messaging. Chapter 6, “Legacy Integration,” shows how to use the WCF to integrate with Microsoft technologies such as MSMQ and COM+. In addition to integration, the Windows Communication Foundation also provides significant benefits when it comes to interoperability. This chapter examines how to interoperate with other systems using Web services.

WCF is part of WinFX and has a dependency on the .NET Framework 2.0. For scenarios in which a client is running an earlier version of the framework, using a non-.NET language, and/or running on another platform, interoperability becomes critical.

This chapter demonstrates interoperability in several varieties seen in the real world. The first example involves creating a WCF client that connects to an existing ASMX Web service. Next, you will create a simple WCF service, and then create both a WCF client and an ASMX client to consume it.

An Overview of Interoperability

One of the key values of SOAP is that it is platform agnostic. Regardless of the platform a system may be on, there is potential to readily interoperate with others.

WS-I Basic Profile

Through the .NET Framework and the SOAP Toolkit, Microsoft provided the capability to create Web services hosted within Internet Information Server (IIS). The more common .NET Web services were stored in files with an extension of .ASMX and are commonly referred to as ASMX Web Services. Other software companies created their own Web service implementations, and subtle differences among the implementations caused some challenges when they attempted to interoperate using other tools, languages, and/or platforms.

The Web Services Interoperability Organization (http://www.ws-i.org) creates, promotes, and supports generic protocols for the interoperable exchange of messages between Web services. The WS-I has published a profile of what must be supported for basic interoperability.

To facilitate interoperability, the WS-I established a working group for a basic profile that could be implemented to support interoperability across implementations and platforms. The Basic Profile 1.1 (BP1.1) consists of implementation guidelines recommending how a set of core Web services specifications should be used together to develop interoperable Web services. The guidelines address technologies that cover the following areas:

  • Messaging—The exchange of protocol elements, usually over a network, to affect a Web service

  • Description—The enumeration of the messages associated with a Web service, along with implementation details

  • Discovery—Metadata that enables the advertisement of a Web service’s capabilities

  • Security—Mechanisms that provide integrity and privacy

BP 1.1 covers the following core Web services standards and provides constraints and clarifications to these base specifications, along with conventions about how to use them together, with the goal of promoting interoperability:

  • SOAP 1.1

  • WSDL 1.1

  • UDDI 2.0

  • XML 1.0 (Second Edition)

  • XML Schema Part 1: Structures

  • XML Schema Part 2: Data types

  • RFC2246: The Transport Layer Security Protocol Version 1.0

  • RFC2459: Internet X.509 Public Key Infrastructure Certificate and CRL Profile

  • RFC2616: Hypertext Transfer Protocol 1.1

  • RFC2818: HTTP over TLS Transport Layer Security

  • RFC2965: HTTP State Management Mechanism

  • The Secure Sockets Layer Protocol Version 3.0

To provide Basic Profile support in WCF is very straightforward, just specify the basicHttpBinding.

WS-*

Although having Basic Profile 1.1 is important, as the name implies, it is for basic interoperability. The functionality provided by the BP 1.1 does not address many of the needs critical to many real-world scenarios, particularly around security and reliability.

Much of what is supported by the Basic Profile is designed for services that have direct connections with their clients. In the emerging world of service-oriented Enterprises, messages no longer go strictly from a service at Point A to a client at Point B; instead a message may make multiple “hops” en route to its destination. This requires involvement not at the transport level, but at the message level.

When examining security in the Basic Profile, the channel between the server and its clients can be secured using SSL. Both server and client authenticity can be validated using certificates. This is typically acceptable when you’re interacting in a scenario in which there is a 1:1 connection. But what about when you send a message, that message is then routed, and eventually it reaches its recipient? There could be any number of hops in between client and service, and the path is likely to vary based on various criteria (traffic, SLAs, and so on). Although setting up transport security with BP 1.1 could be done, this process now introduces a number of intermediaries and introduces the potential risk that messages could be modified en route. There was a need for standards around key areas in this space, with major focuses on security, transactions, and reliability. OASIS has been the leader in driving these standards.

OASIS (Organization for the Advancement of Structured Information Standards) is a not-for-profit, international consortium that drives the development, convergence, and adoption of e-business standards. Microsoft, IBM, SAP AG, Nokia, Oracle, and BEA Systems are among the 600 organizations that participate in OASIS.

The participants in OASIS have put forward a number of standards for advanced Web services, referred to collectively as the WS-* specifications. In WCF, WS-* interoperability includes platform-agnostic support of reliable sessions, transactions, transport security, and SOAP security.

To provide WS-* support to your services, use the wsHttpBinding.

Custom Bindings

In addition to the bindings provided with Windows Communication Foundation out of the box, WCF provides the capability to create custom bindings in the configuration file. This allows tremendous flexibility when interoperating with business partners, legacy systems, third-party products, and commercial Web services when the standard bindings provided do not meet the requirements of your service. Custom binding elements could be used, for example, to enable the use of new transports or encoders at a service endpoint. Custom bindings are used to define a binding from a set of binding elements.

Creating Proxy Code for Use in Client Applications

To facilitate the creation of client proxies, Windows Communication Foundation includes the Service MetaData Utility tool (SvcUtil.exe). This tool generates service model code from metadata documents and metadata documents from service model code.

In this chapter, we’ll use the tool to generate proxy code to be used in interop scenarios. At least up until the February CPT release, it does not automatically map the preconfigured bindings by name. Instead, custom bindings will be created that map to the requirements of the service.

SvcUtil.exe is called using the command line and parameters found in Table 7.1.

Svcutil [options] [metadataPath* | assemblyPath* | metadataUrl*]

Table 7.1. Parameters for SvcUtil.exe

Argument

Description

metadataPath

Path to metadata document that contains the contract to import into code (.wsdl, .xsd, .wspolicy, or .wsmex).

AssemblyPaths

Path to the assembly file that contains service contracts to export to metadata.

metadataUrl

URL to the running Web service that provides metadata for download through WS-Metadata Exchange or Http-Get.

Option

Description.

/directory:< directory>

Directory to create files in.

Default: The current directory.

Short form: /d.

/out:<file>

File name for the generated code.

Default: Derived from the service name or target namespace of the schema document.

Short form: /o.

/target:[code | metadata]

Specifies the output to be generated by the tool.

Default: Inferred from input.

Short form: /t.

/validate

Instructs the tool to validate all service endpoints in associated config files. (A config file is loaded when an exe for the config file is passed to the tool.)

Short form: /w.

/config:<file1 [, file2]>

Instructs the tool to generate a configuration file. If only one filename is given, that is the name of the output file. If two filenames are given, the first file is an input configuration file whose contents are merged with the generated configuration and written out into the second file.

/noConfig

Do not create a config file.

/svcutilConfig:<file>

Custom configuration file to use in place of the app config file. Allows the user to change metadata configuration without altering global app config settings.

/language:<language>

Specifies the programming language to use for code generation. Values: c#, cs, csharp, vb, vbs, visualbasic, vbscript, js, jscript, javascript, vj#, vjs, vjsharp, c++, mc, or cpp, or provide a fully qualified name for a class implementing System.CodeDom.Compiler.CodeDomProvider. Default: csharp.

Short form: /l.

/compile

Compiles generated code into an assembly.

Short form: /c.

/namespace:<”schema

Specifies the CLR namespace to associate with a schema target

namespace”, “CLR namespace”>

namespace.

Default: Derived from the target namespace of the schema document.

Short form: /n.

/reference:<file path>

References the specified assembly files.

Short form: /r.

/nostdlib

Do not reference standard library (mscorlib.dll).

/referenceCollectionType:<type list>

Fully qualified or assembly-qualified type name to exclude from referenced types.

Short form: /rct.

/excludeType:<type>

Fully qualified or assembly-qualified type name to exclude from referenced types.

Short form: /et.

/async

Generate asynchronous method signatures.

Short form: /a.

/internal

Generate classes marked internal (default: generate public classes).

Short form: /i.

/typedMessages

Instructs the tool to generate code that uses typed messages.

Short form: /tm.

/useXmlSerializer

Instructs the tool to generate code that uses XmlSerializer.

Short form: /uxs.

/importXmlType

Import non-Data Contract types as IXmlSerializable.

Short form: /ixt.

/enableDataBinding

Implement INotifyPropertyChanged interface on all XmlFormatter types to enable data binding.

Short form: /edb.

/dataContractOnly

Instructs the tool to operate on Data Contract types only.

Service Contracts will not be processed.

Short form: /dconly.

/noLogo

Suppress the copyright and banner message.

/help

Displays command syntax and options for the tool.

Short form: /?.

Creating a WCF Client for an ASMX Service with SvcUtil.exe

The following exercise creates a client for a very simple ASMX Web service with one web method, InteropHelloWorld. As you can see in the Listing 7.1, this method for that service receives a string parameter, Name, and returns a string value.

Example 7.1. ASMX Service Code

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service () {

    }

    [WebMethod]
    public string InteropHelloWorld(string Name) {
        return "Hello " + Name + ", you've just interop'd.";

    }
}

This service was deployed using the setup script available at the publisher’s website.

Validate that the service is online and create the proxy for the client:

  1. Test that the service is online and available.

  2. Open Internet Explorer, and navigate to the following URL:

    http://localhost/WCFHandsOn/InteropHelloWorld/Service.asmx

    This should display a page that lists the operations supported by this service. If this does not display, validate that the virtual directory exists and is pointing to C:AppsWCFHandsOnChapter7PartIAfterInteropHelloWorld.

  3. In the open solution, add a new project.

  4. Create a new Windows Console application in C:WCFHandsOnChapter7BeforePartIWCFClient.

  5. Add a reference to System.ServiceModel.

    Now you will create the proxy for the ASMX service.

  6. Open a Visual Studio command prompt and navigate to the directory C:WCFHandsOnChapter7BeforePartIWCFClient.

    Enter the following at the command prompt:

    "C:Program FilesMicrosoft SDKsWindowsv1.0BinSvcUtil.exe " http://localhost/
    ASMX Service CodeWCFHandsOn/InteropHelloWorld/Service.asmx?wsdl/out:proxy.cs

    SvcfUtil.exe generates two files, proxy.cs and output.config.

    Proxy.cs contains a generated proxy class for the ASMX Web service. Output.config contains the configuration information for the service that can be inserted into the application configuration file (App.config).

  7. Within Visual Studio, add both of these files to the WCFClient project.

  8. Rename output.config to App.config.

  9. Using Solution Explorer, open the App.config file and examine its contents:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
           <system.serviceModel>
                  <client>
                      <endpoint address="http://localhost/WCFHandsOn/InteropHelloWorld/Service
    ASMX Service Code.asmx"
                         bindingConfiguration="ServiceSoap" binding="customBinding"
                         name="ServiceSoap" contract="ServiceSoap" />
                      <endpoint address="http://localhost/WCFHandsOn/InteropHelloWorld/Service
    ASMX Service Code.asmx"
                         bindingConfiguration="ServiceSoap12" binding="customBinding"
                         name="ServiceSoap1" contract="ServiceSoap" />
                  </client>
                  <bindings>
                      <customBinding>
                          <binding name="ServiceSoap">
                              <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" 
    ASMX Service CodemessageVersion="Soap11Addressing1" writeEncoding="utf-8 />
                              <httpTransport manualAddressing="false"
    ASMX Service Code maxBufferPoolSize="524288" maxMessageSize="65536" allowCookies="false"
    ASMX Service Code authenticationScheme="Anonymous" bypassProxyOnLocal="false"
    ASMX Service Code ostNameComparisonMode="StrongWildcard" mapAddressingHeadersToHttpHeaders="true"
    ASMX Service Code proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered"
    ASMX Service Code unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" />
                  </binding>
                  <binding name="ServiceSoap12">
                         <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" 
    ASMX Service CodemessageVersion="Default" writeEncoding="utf-8" />
                         <httpTransport manualAddressing="false"
    ASMX Service Code maxBufferPoolSize="524288"maxMessageSize="65536" allowCookies="false"
    ASMX Service Code authenticationScheme="Anonymous" bypassProxyOnLocal="false"
    ASMX Service Code hostNameComparisonMode="StrongWildcard" mapAddressingHeadersToHttpHeaders="true"
    ASMX Service Code proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered"
    ASMX Service Code unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" />
                         </binding>
                     </customBinding>
                 </bindings>
              </system.serviceModel>
    </configuration>

    Notice that SvcUtil has created the two endpoints ServiceSoap and ServiceSoap1 for InteropHelloWorldService.

    If you look at the WSDL document exposed by our ASMX service, you’ll notice that these endpoints were created from the port information in that document:

    <wsdl:service name="Service">
    <wsdl:port name="ServiceSoap" binding="tns:ServiceSoap">
    <soap:address location="http://localhost:8000/WCFHandsOn/InteropHelloWorld/Service.asmx" />
    </wsdl:port>
    <wsdl:port name="ServiceSoap12" binding="tns:ServiceSoap12">
    <soap12:address location="http://localhost:8000/WCFHandsOn/InteropHelloWorld/Service.asmx" />
    </wsdl:port>
    </wsdl:service>

    Also note that SvcUtil.exe creates custom bindings for each of these. Each of these displays a number of the configurable attributes that can be set, highlighting the flexibility available for interoperability.

  10. From Solution Explorer, open proxy.cs.

    This is the proxy class created by SvcUtil.exe. Notice that the ServiceSoap interface was defined, containing a single operation that was in our service.

    In addition, a ServiceSoapProxy class was created. Note that in addition to several constructors for the class, the class also implements the ServiceSoap interface. When InteropHelloWorld is called on the proxy, it will call the operation on our ASMX service:

    [System.ServiceModel.ServiceContractAttribute(Namespace="http://Samples.Microsoft.Com/")]
    public interface ServiceSoap
    {
    
        [System.ServiceModel.OperationContractAttribute(Action="http://Samples.Microsoft.Com
    ASMX Service Code/InteropHelloWorld", ReplyAction="http://Samples.Microsoft.Com/InteropHelloWorld")]
        string InteropHelloWorld(string Name);
    }
    
    public interface ServiceSoapChannel : ServiceSoap, System.ServiceModel.IClientChannel
    {
    }
    
    public partial class ServiceSoapProxy : System.ServiceModel.ClientBase<ServiceSoap>,
    ASMX Service Code ServiceSoap
    {
    
        public ServiceSoapProxy()
        {
        }
    
        public ServiceSoapProxy(string endpointConfigurationName) :
                base(endpointConfigurationName)
        {
        }
    
        public ServiceSoapProxy(string endpointConfigurationName, string remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public ServiceSoapProxy(string endpointConfigurationName, System.ServiceModel
    ASMX Service Code.EndpointAddress remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public ServiceSoapProxy(System.ServiceModel.Binding binding, System.ServiceModel
    ASMX Service Code.EndpointAddress remoteAddress) :
                base(binding, remoteAddress)
        {
        }
        public string InteropHelloWorld(string Name)
        {
            return base.InnerProxy.InteropHelloWorld(Name);
        }
    }

    Now that we have a proxy class and a configuration file, let’s write the code to call the service.

  11. Using Solution Explorer, open the file Program.cs.

  12. Add using System.ServiceModel; to the top of the Program.cs file:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceModel;
  13. Modify the Main method in Program.cs to include the lines listed in bold in the following code:

    static void Main(string[] args)
    {
        ServiceSoapProxy proxy = new ServiceSoapProxy("ServiceSoap");
        Console.WriteLine("What's your name?");
        string name = Console.ReadLine().ToString();
        Console.WriteLine(proxy.InteropHelloWorld(name));
    
        Console.WriteLine("------------------------");
        Console.WriteLine("Press Any Key To Exit");
        Console.ReadLine();
    
    }

    Note that we chose to reference the constructor that takes a configurationName as a parameter. At runtime, the name provided will be used to reference the appropriate endpoint, bindings, and contract in the App.config file.

  14. Using Solution Explorer, right-click the WCFClient project and select Set as Startup Project.

  15. From the Debug menu, select Start Debugging.

After you’ve entered your name at the prompt, the client will call out to the ASMX service and display the result.

Creating a WCF Service and WCF/ASMX Clients

In this next example, we’ll look at interoperability from the other direction. Here we’ll create a WCF service and then create ASMX and WCF clients that utilize it.

Creating the WCF Service

To create the new service project, follow these steps:

  1. Open Visual Studio and add a new project. Create a new Windows Console application in C:WCFHandsOnChapter7BeforePartIIInteropHelloWorld2.

  2. Add a Reference to System.ServiceModel.

  3. Using Solution Explorer, open the file Program.cs.

  4. Add using System.ServiceModel; to the top of the Program.cs file:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceModel;

    This service will expose one operation, InteropHelloWorld. First, add the interface IInteropHelloWorld to the Program.cs file.

  5. Enter the following interface code:

    namespace Samples.Microsoft.Com
    {
       [ServiceContract]
       public interface IInteropHelloWorld
       {
         [OperationContract]
         string InteropHelloWorld(string Name);
       }

    With the interface defined, we can now add the class for our service that implements it.

  6. Enter the following code for the class:

    public class InteropHelloWorld2 : IInteropHelloWorld
    {
    
        public string InteropHelloWorld(string Name)
        {
           return "Hello " + Name + ", you've just interop'd.";
        }
    }

    For this exercise, the service will not be be hosted within IIS, but is instead hosted inside of a Windows Console application.

    This requires the creation of a ServiceHost object to instantiate the service. When a new ServiceHost is being created, information regarding the service is provided in the constructor. In this case, we specify the serviceType that maps to the name of the class:

        static void Main(string[] args)
        {
            ServiceHost service =
              new ServiceHost(typeof(InteropHelloWorld2));
            service.Open();
            Console.WriteLine("Service is available.");
            Console.ReadLine();
         }

    Now we can create the App.config file and configure the service.

  7. Add a new application configuration file to the project and accept the default name of App.config.

    Open the configuration file and enter the information for the service’s abc’s (address, binding, contract) as seen here:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
       <appSettings>
          <!-- use appSetting to configure base address provided by host -->
          <add key="baseAddress" value="http://localhost:8080/WCFHandsOn/InteropHelloWorld2" />
    </appSettings>
      <system.serviceModel>
             <services>
                  <service type="Samples.Microsoft.Com.InteropHelloWorld2">
                       <endpoint address="" binding="basicHttpBinding" contract="Samples
    Creating the WCF Service.Microsoft.Com.IInteropHelloWorld"/>
                   </service>
               </services>
            </system.serviceModel>
    </configuration>

    Our base address is specified in the appSettings setting, because we’ll be setting this value inside of the code. Also note that the endpoint for this service is being made available on port 8000 of the local server. Because this is running in a console application and is not hosted within Internet Information Server, we’ve specified a separate port. Note that we are using the basicHttpBinding, and the service will be compliant with BP 1.0. Finally, note that the contract consists of the concatenation of the namespace and the interface for the service.

    With the application configuration file populated, the project is now ready to be compiled.

  8. Build the project.

  9. Using Windows Explorer, navigate to the InteropHelloWorld2.exe just created and run the InteropHelloWorld2 service. The full path to the file is C:WCFHandsOnChapter7PartIIBeforeInteropHelloWorld2InteropHelloWorld2inDebugInteropHelloWorld2.exe.

With the service now running, it is available for clients to query it for metadata and interact with it.

Creating a WCF Client

Creating the WCF client for our WCF service will be virtually identical to how we created the WCF client for the ASMX service in the initial example, using SvcUtil.exe:

  1. Create a new Windows Console project in C:WCFHandsOnChapter7PartIIBeforeWCFClient.

  2. Add a Reference to System.ServiceModel.

  3. Open Visual Studio.NET Command Window.

  4. Execute the SvcUtil.exe utility, pointing it at the WCF Service. This creates both a proxy and a configuration file to be used by the client:

    "c:Program FilesMicrosoft SDKsWindowsv1.0BinSvcUtil.exe" http://localhost:8000
    Creating a WCF Client/WCFHandsOn/InteropHelloWorld2 /out:proxy.cs
  5. Using Solution Explorer, add proxy.cs to the WCFClient project.

  6. Using Solution Explorer, add output.config to the WCFClient project.

  7. Rename output.config to App.config.

  8. Place the following code in the Main method in the Program.cs file:

    static void Main(string[] args)
    {
       Console.WriteLine("Please enter your name");
       string Name = Console.ReadLine();
       InteropHelloWorldProxy hello = new InteropHelloWorldProxy();
       Console.WriteLine("This is the message from the WCF Web Service:");
       Console.WriteLine(hello.InteropHelloWorld(Name));
       Console.ReadLine();
    }
  9. In Solution Explorer, right-click the project and select Debug, Start New Instance.

The client will prompt you for your name. It will then call the InteropHelloWorld service and write the response to the console.

Creating an ASMX Client

There are very straightforward ways to enable ASMX clients to access your Windows Communication Foundation service. For projects in which clients will have both the .NET Framework 2.0 and WinFX installed, SvcUtil.exe can be used, as it was in the preceding example. In that environment, the proxy.cs and output.config files generated by SvcUtil.exe could be added to an ASMX Web service project without modification.

If your service consumers do not have WinFX installed and/or are unfamiliar with SvcUtil.exe, they can consume your BP 1.1 Web service as they would any other Web service, using the Add Web Reference functionality built into Visual Studio. The WCF service exposes both WSDL and MEX metadata, which can be used by programmers and development tools to consume the service on any platform.

This example looks at creating an ASMX client for the WCF Service created earlier.

Rather than using SvcUtil.exe, which requires the .NET Framework 2.0, as mentioned earlier, we’ll use the Add Web Reference facility that’s been available since the initial release of VisualStudio.NET. It is important to note that while WCF requires the .NET Framework 2.0, clients for BP 1.1 services can be created using earlier versions of the framework and Visual Studio.NET:

  1. Within VisualStudio.NET, create a new website at C:WCFHandsOnChapter7PartIIBefore.

  2. Name the website ASMXClient.

  3. In Solution Explorer, add a web reference to the project.

    When prompted in the Add Web Reference dialog, enter the following URL: http://localhost:8000/WCFHandsOn/InteropHelloWorld2?wsdl

    With the web reference set, the ASMX client will now utilize the service within its own service. When the project was created, a file Service.cs was added to the project in the project’s App_Code directory.

  4. Open this file now and add the code for the WebMethod:

    using System;
    using System.Web;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    
    [WebService(Namespace = "http://Samples.Microsoft.Com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Service : System.Web.Services.WebService
    {
        public Service () {
    
        }
    
    [WebMethod]
    public string HelloWorldAsmx(string Name) {
         localhost.InteropHelloWorld2 hello = new localhost.InteropHelloWorld2();
    
         return "This is the message from the WCF Web Service" + hello.InteropHelloWorld(Name); ;
        }
    
    }
  5. Using the Internet Information Services Manager, create a new virtual directory. The new directory should use the alias WCFHandsOn_ASMXClient and the local path for the virtual directory should point to the location of the project, C: WCFHandsOnChapter7PartIIBeforeASMXClient.

  6. Using VisualStudio.NET, build the project.

  7. Finally, test the “client” ASMX service by opening Internet Explorer and entering the URL for the service, http://localhost/WCFHandsOn/ASMXClient/Service.asmx.

Creating a WCF Client for a Lotus Notes Domino Server Web Service

Lotus Notes is a popular messaging and collaboration tool sold by IBM. Lotus Notes Domino is a Web server designed to publish information from the Notes data stores. Domino currently provides the capability to expose BP 1.1 services for use in client applications and scenarios such as B2B. Although Lotus does have client development tools, Enterprises that utilize notes and the consumers of Domino-published content may want to develop clients using Visual Studio.NET. This is particularly desirable for many companies looking to take advantage of technologies such as the Windows Presentation Foundation (WPF) for a rich user experience, the Workflow Foundation (WF) for workflow, and the Windows Communication Foundation (WCF) for secure, reliable, transacted services.

Fortunately, it’s very easy to do this using the same SvcUtil.exe utility that we used in the preceding exercise.

Microsoft has a licensed copy of Domino Server running the site http://www.msdomino.net that is populated with content by our colleague Gary Devendorf. Gary is a Technical Evangelist at Microsoft, and he helps customers interoperate between Lotus and Microsoft technologies, or migrate over from Lotus to Microsoft solutions.

On this site, Gary has created a Web service for placing orders over the web that are deposited in a Lotus Notes database. This Web service provides operations that allow you to place an order, change the status of an order, and check the status of an order.

In this exercise, you will create a console application that places an order and immediately checks the status of that order. It then calls the service to change the status to Approved and check the status once more. As part of testing the service, we’ll go to a Domino web page to validate that the order has been received and has been approved.

Creating the WCF client for our WCF service will be virtually identical to how we created the WCF client for the ASMX and WCF services in the earlier example, using SvcUtil.exe. In this case, we’re using the same approach to interoperate with a non-Microsoft Web server:

  1. Create a new Windows Console project in C:WCFHandsOnChapter7PartIIIBeforeDominoClient.

  2. Add a Reference to System.ServiceModel.

  3. Add using System.ServiceModel; to the top of the Program.cs file:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceModel;
  4. Open Visual Studio.NET Command Window.

  5. Execute the SvcUtil.exe utility with a reference to the service to create a proxy and configuration file to be used by the client.

    "c:Program FilesMicrosoft SDKsWindowsv1.0BinSvcUtil.exe " http://www.msdomino.net
    Creating a WCF Client for a Lotus Notes Domino Server Web Service/msorders.nsf/create_order?WSDL/out:proxy.cs
  6. Using Solution Explorer, add proxy.cs to the DominoClient project.

  7. Using Solution Explorer, add output.config to the DominoClient project.

  8. Rename output.config to App.config.

  9. Open the App.config file.

    In the client section, add a name for our endpoint that we will use when calling the service by adding the text name=”DominoOrders”:

    <client>
        <endpoint name=”DominoOrders” address= http://www.msdomino.net:80/msorders.nsf/
    Creating a WCF Client for a Lotus Notes Domino Server Web Servicecreate_order?OpenWebService bindingConfiguration=”DominoSoapBinding”
    Creating a WCF Client for a Lotus Notes Domino Server Web Service binding=”customBinding” contract=”Update” />
    </client>

    You will now enter the core information for the client. Although there are sample values in the following code for the parameters (such as weight, shipAddress, shipCity), feel free to modify these.

  10. Place the following code in the Main method in the Program.cs file:

    static void Main(string[] args)
    {
            using (UpdateProxy proxy = new UpdateProxy("DominoOrders"))
            {
                   string customerID = "1";
                   string orderDate = "10/25/2006";
                   string weight = "50";
                   string freight = "100";
                   string shipAddress = "1 main street";
                   string shipCity = "Redmond";
                   string shipCountry = "USA";
                   string amount = "500.00";
    
                   //PLACE THE ORDER
                   int orderID = proxy.NEWORDER(customerID,orderDate,amount,freight, weight, 
    Creating a WCF Client for a Lotus Notes Domino Server Web ServiceshipAddress, shipCity, shipCountry);
                   System.Console.WriteLine("Your order was placed. Your order ID for future 
    Creating a WCF Client for a Lotus Notes Domino Server Web Servicereference is " + orderID.ToString());
    
    
                   //CHECK THE STATUS OF THE ORDER
                   System.Console.WriteLine
    Creating a WCF Client for a Lotus Notes Domino Server Web Service("----------------------------------------------------------------------------");
                   string status = proxy.CHECKSTATUS(orderID);
                   System.Console.WriteLine();
                   System.Console.WriteLine("Your order status is: " + status);
    
                   //APPROVE THE ORDER
                   System.Console.WriteLine
    Creating a WCF Client for a Lotus Notes Domino Server Web Service("----------------------------------------------------------------------------");
                   System.Console.WriteLine("Cancelling order#" +
    orderID.ToString());
                   proxy.CHANGESTATUS(orderID, "Approved");
                   // CHECK THE ORDER STATUS, TO SEE IF IT'S APPROVED
                   System.Console.WriteLine
    Creating a WCF Client for a Lotus Notes Domino Server Web Service("----------------------------------------------------------------------------");
                   status = proxy.CHECKSTATUS(orderID);
                   System.Console.WriteLine();
                   System.Console.WriteLine("Your order status is: " + status);
                   System.Console.ReadLine();
    
           }
    }
  11. In Solution Explorer, right-click the project and select Debug, Start New Instance.

    The client will then print out several messages in the console window, identifying that the order has been placed, the order ID assigned by the server, and that the order has been approved. Make a note of the order ID, because we will now validate that this was accepted on the server.

    Go to the page on Domino to view the results.

  12. Open your web browser and navigate to http://www.msdomino.net/msorders.nsf.

    You should see a web page with several links on it, as shown in Figure 7.1.

    Lotus Domino Web server page.

    Figure 7.1. Lotus Domino Web server page.

  13. Click on the Approved Orders link. This will display a list of all the orders that have been approved (see Figure 7.2).

    The Approved Orders page on the Lotus Domino Web server.

    Figure 7.2. The Approved Orders page on the Lotus Domino Web server.

  14. To complete the exercise, validate that your order ID is included in the list of approved orders.

Two for the Road

We’ve just done interop with a product from IBM; now let’s continue down the path by creating test clients for two other major players, Oracle and Sun Microsystems. From a technology perspective, we’ll be revisiting what we’ve done earlier in the chapter. So why include this in the book? To underscore the value that standards—and a tool such as WCF that is built on standards—provide to the Enterprise. The SvcUtil.exe utility reads platform-agnostic WSDL files, and we’re up and interoperating in minutes.

Create a WCF Client to Test Interop with Sun Microsystems

Sun Microsystems has a public-facing Web service that can be used for interoperability testing. This service is provided solely for interoperability tests, so its operations are limited to “echoes.” These operations will receive a value of a particular type, such as a string, and will return that same value to the caller:

  1. Create a new Windows Console project in C:WCFHandsOnChapter7PartIVBeforeSunClient.

  2. Add a Reference to System.ServiceModel.

  3. Add using System.ServiceModel; to the top of the Program.cs file:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceModel;
  4. Open Visual Studio.NET Command Window.

  5. Execute the SvcUtil.exe utility with a reference to the service to create a proxy and configuration file to be used by the client.

    "c:Program FilesMicrosoft SDKsWindowsv1.0BinSvcUtil.exe " http://soapinterop.java
    Create a WCF Client to Test Interop with Sun Microsystems.sun.com/round2/base?WSDL /out:proxy.cs
  6. Using Solution Explorer, add proxy.cs to the SunClient project.

  7. Using Solution Explorer, add output.config to the SunClient project.

  8. Rename output.config to App.config.

    Open App.config and add a name for the endpoint. Add the text name=“SunInterop” to the endpoint element in the client section of the config file:

    <client>
        <endpoint name="SunInterop" address="http://soapinterop.java.sun.com:80/round2/base"
        bindingConfiguration="RIBaseBinding" binding="customBinding"
        contract="RIBaseIF" />
    </client>
  9. Place the following code in the Main method in the Program.cs file:

    static void Main(string[] args)
    {
      RIBaseIFProxy proxy = new RIBaseIFProxy("SunInterop");
      System.Console.WriteLine("Enter in the phrase to tell Sun");
      String repeatText = System.Console.ReadLine();
      System.Console.WriteLine();
      System.Console.WriteLine("Sun – if you can understand me, repeat after me:" + repeatText);
      System.Console.WriteLine("Sun says:" + proxy.echoString(repeatText));
      System.Console.ReadKey();
    }
  10. In Solution Explorer, right-click the project and select Debug, Start New Instance.

The client will prompt you for some text to send to Sun. It will then contact the Sun Web service, which will return that same text.

Create a WCF Client to Test Interop with Oracle Application Server

Oracle has a public-facing website and services for its Oracle Application Server 10g. There is a public-facing Web service attached to the product. This service has several username and password controlled services; however, we’re interested only in testing interop. In this exercise, we’ll create a client that tests the GetVersion operation, which does not require a username or password:

  1. Create a new Windows Console project in C:WCFHandsOnChapter7PartIVBeforeOracleClient.

  2. Add a Reference to System.ServiceModel.

  3. Add using System.ServiceModel; to the top of the Program.cs file:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceModel;
  4. Open Visual Studio.NET Command Window.

  5. Execute the SvcUtil.exe utility with a reference to the service to create a proxy and configuration file to be used by the client.

    "C:Program FilesMicrosoft SDKsWindowsv1.0BinSvcutil.exe " /out:proxy.cs http:/
    Create a WCF Client to Test Interop with Oracle Application Server/messenger.oracle.com/xms/webservices?WSDL
  6. Using Solution Explorer, add proxy.cs to the OracleClient project.

  7. Using Solution Explorer, add output.config to the OracleClient project.

  8. Rename output.config to App.config

    Open App.config and add a name for the endpoint. Add the text name=”OracleInterop” to the endpoint element in the client section of the config file:

    <client>
        <endpoint name="OracleInterop" address= "http://notify.multimodeinc.com/xms/webservices"
        bindingConfiguration="XMSServerBinding" binding="customBinding"
        contract="XMSServerPortType" />
    </client>
  9. Place the following code in the Main method in the Program.cs file:

    static void Main(string[] args)
    {
    
       //ORACLE
       XMSServerPortTypeProxy proxy = new XMSServerPortTypeProxy("OracleInterop");
       string version = proxy.getVersion();
       System.Console.WriteLine("The version of Oracle currently running is:" + version);
       System.Console.ReadLine();
    }
  10. In Solution Explorer, right-click the project and select Debug, Start New Instance.

The client will connect to the Oracle service, return the current version, and display it in the console.

Summary

In this chapter we saw the power of Windows Communication Foundation to interoperate. WCF on the server provides the capability to interoperate with various systems, and this chapter showed how to interoperate with ASMX services in client and service scenarios. In addition, we saw examples for how to interoperate with existing technologies from Microsoft, Oracle, IBM, and Sun.

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

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