Using the WCF Moniker with COM Clients

Download sample

This sample demonstrates how to use the Windows Communication Foundation (WCF) service moniker to integrate Web services into COM-based development environments, such as Microsoft Office Visual Basic for Applications (Office VBA) or Visual Basic 6.0. This sample consists of a Windows Script Host client (.vbs), a supporting client library (.dll), and a service library (.dll) hosted by Internet Information Services (IIS). The service is a calculator service and the COM client calls math operations—Add, Subtract, Multiply, and Divide—on the service. Client activity is visible in the message box windows.

Note

The WCF samples may already be installed on your machine. Check for the following (default) directory before continuing.

<InstallDrive>:\Samples\WCFWFCardspace

If this directory does not exist, click the download sample link at the top of this page. Note that this link downloads and installs all of the WF, WCF, and CardSpace samples. The sample is located in the following directory.

<InstallDrive>:\Samples\WCFWFCardSpace\WCF\Basic\Service\Interop\COM

Note

The set up procedure and build instructions for this sample are located at the end of this topic.

The service implements an ICalculator contract defined as follows:

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);
    [OperationContract]
    double Subtract(double n1, double n2);
    [OperationContract]
    double Multiply(double n1, double n2);
    [OperationContract]
    double Divide(double n1, double n2);
}

The sample demonstrates the three alternative approaches for using the moniker:

  • Typed contract – The contract is registered as a COM visible type on the client machine.

  • WSDL contract – The contract is supplied in the form of a WSDL document.

  • Metadata Exchange contract – The contract is retrieved at runtime from a Metadata Exchange (MEX) endpoint.

Typed Contract

To use the moniker with a typed contract use, appropriately attributed types for the service contract must be registered with COM. First, a client must be generated by using the Service Model Metadata Utility Tool (Svcutil.exe). Run the following command from a command prompt in the client directory to generate the typed proxy:

svcutil.exe /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost/servicemodelsamples/service.svc /out:generatedClient.cs

This class must be included in a project and the project should be configured to generate a COM-visible, signed assembly when compiled. The following attribute should be included in the AssemblyInfo.cs file:

[assembly: ComVisible(true)]

After building the project, register the COM-visible types by using regasm:

regasm.exe /tlb:CalcProxy.tlb client.dll

The assembly that is created should be added to the Global Assembly Cache. Though not strictly required, this simplifies the process of the runtime locating the assembly. The following command adds the assembly to the Global Assembly Cache:

gacutil.exe /i client.dll

Note

The service moniker requires only the type registration and does not use the proxy to communicate with the service.

ComCalcClient.vbs client application uses the GetObject function to construct a proxy for the service, using the service moniker syntax to specify the address, binding, and contract for the service.

Set typedServiceMoniker = GetObject(
"service:address=https://localhost/ServiceModelSamples/service.svc, binding=wsHttpBinding, 
contractType={9213C6D2-5A6F-3D26-839B-3BA9B82228D3}")

The parameters used by the moniker specify:

  • The address of the service endpoint.

  • The binding that the client should use to connect with that endpoint. In this case, the system-defined wsHttpBinding is used though custom bindings can be defined in client configuration files. For use with the Windows Script Host, the custom binding is defined in a Cscript.exe.config file in the same directory as Cscript.exe.

  • The type of the contract that is supported at the endpoint. This is the type that was generated and registered above. Because Visual Basic script does not provide a strongly-typed COM environment, an identifier for the contract must be specified. This GUID is the interfaceID from CalcProxy.tlb, which can be viewed by using COM tools such as the OLE/COM Object Viewer (OleView.exe). For strongly-typed environments such as Office VBA or Visual Basic 6.0, adding an explicit reference to the type library and then declaring the type of the proxy object can be used in place of the contract parameter. This also provides IntelliSense support during client application development.

Having constructed the proxy instance with the service moniker, the client application can call methods on the proxy, which results in the service moniker infrastructure calling the corresponding service operations:

' Call the service operations using the moniker object
WScript.Echo "Typed service moniker: 100 + 15.99 = " & typedServiceMoniker.Add(100, 15.99)

When you run the sample, the operation response is displayed in a Windows Script Host message box window. This demonstrates a COM client making COM calls using the typed moniker to communicate with a WCF service. Despite the use of COM in the client application, the communication with the service consists only of Web service calls.

WSDL Contract

To use the moniker with a WSDL contract, no client library registration is required but the WSDL contract for the service must be retrieved through an out-of-band mechanism such as using a browser to access the WSDL endpoint for the service. The moniker can then access that contract at execution time.

The ComCalcClient.vbs client application uses the FileSystemObject to access the locally saved WSDL file and then again uses the GetObject function to construct a proxy for the service:

' Open the WSDL contract file and read it all into the wsdlContract string
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("serviceWsdl.xml", ForReading)
wsdlContract = objFile.ReadAll
objFile.Close

' Create a string for the service moniker including the content of the WSDL contract file
wsdlMonikerString = "service:address='https://localhost/ServiceModelSamples/service.svc'"
wsdlMonikerString = wsdlMonikerString + ", binding=WSHttpBinding_ICalculator, bindingNamespace='http://Microsoft.ServiceModel.Samples'"
wsdlMonikerString = wsdlMonikerString + ", wsdl='" & wsdlContract & "'"
wsdlMonikerString = wsdlMonikerString + ", contract=ICalculator, contractNamespace='http://Microsoft.ServiceModel.Samples'"

' Create the service moniker object
Set wsdlServiceMoniker = GetObject(wsdlMonikerString)

The parameters used by the moniker specify:

  • The address of the service endpoint.

  • The binding that the client should use to connect with that endpoint and the namespace in which that binding is defined. In this case, the wsHttpBinding_ICalculator is used.

  • The WSDL that defines the contract. In this case this is the string that has been read from the serviceWsdl.xml file.

  • The name and namespace of the contract. This identification is required because the WSDL may contain more than one contract.

    Note

    By default, WCF services generate separate WSDL files for each namespace that the use. These are linked with the use of the WSDL import construct. Because the moniker expects a single WSDL definition, the service must either use a single namespace as demonstrated in this sample or the separate files must be manually merged.

Having constructed the proxy instance with the service moniker, the client application can call methods on the proxy, which results in the service moniker infrastructure calling the corresponding service operations:

' Call the service operations using the moniker object
WScript.Echo "WSDL service moniker: 145 - 76.54 = " & wsdlServiceMoniker.Subtract(145, 76.54)

When you run the sample, the operation response is displayed in a Windows Script Host message box window. This demonstrates a COM client making COM calls using the moniker with a WSDL contract to communicate with a WCF service.

Metadata Exchange Contract

To use the moniker with a MEX contract, as with the WSDL contract, no client registration is required. The contract for the service is retrieved at execution time through the internal use of Metadata Exchange.

The ComCalcClient.vbs client application again uses the GetObject function to construct a proxy for the service:

' Create a string for the service moniker specifying the address to retrieve the service metadata from
mexMonikerString = "service:mexAddress='https://localhost/servicemodelsamples/service.svc/mex'"
mexMonikerString = mexMonikerString + ", address='https://localhost/ServiceModelSamples/service.svc'"
mexMonikerString = mexMonikerString + ", binding=WSHttpBinding_ICalculator, bindingNamespace='http://Microsoft.ServiceModel.Samples'"
mexMonikerString = mexMonikerString + ", contract=ICalculator, contractNamespace='http://Microsoft.ServiceModel.Samples'"

' Create the service moniker object
Set mexServiceMoniker = GetObject(mexMonikerString)

The parameters used by the moniker specify:

  • The address of the service metadata exchange endpoint.

  • The address of the service endpoint.

  • The binding that the client should use to connect with that endpoint and the namespace in which that binding is defined. In this case, the wsHttpBinding_ICalculator is used.

  • The name and namespace of the contract. This identification is required because the WSDL may contain more than one contract.

Having constructed the proxy instance with the service moniker, the client application can call methods on the proxy, which results in the service moniker infrastructure calling the corresponding service operations:

' Call the service operations using the moniker object
WScript.Echo "MEX service moniker: 9 * 81.25 = " & mexServiceMoniker.Multiply(9, 81.25)

When you run the sample, the operation response will be displayed in a Windows Script Host message box window. This demonstrates a COM client making COM calls using the moniker with a MEX contract to communicate with a WCF service.

To set up and build the sample

  1. Ensure that you have performed the One-Time Set Up Procedure for the Windows Communication Foundation Samples.

  2. To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  3. From a command prompt, navigate to the \client\bin folder, under the language-specific folder. If using Windows Vista or Windows Server 2008, make sure to run the command prompt as Administrator.

  4. Type in regasm.exe /tlb:CalcProxy.tlb client.dll to register the types with COM. A "Type library exporter warning" is expected but is not an issue because the generic type is not required. Ensure that path has been set to the folder that contains Regasm.exe before you run the command.

  5. Type in gacutil.exe /i client.dll to add the assembly to the Global Assembly Cache. Ensure that path has been set to the folder that contains Gacutil.exe before you run the command.

To run the sample on the same machine

  1. Test that you can access the service using a browser by typing in the following address: https://localhost/servicemodelsamples/service.svc. A confirmation page should be displayed in response.

  2. Run ComCalcClient.vbs from \client, from under the language-specific folder. Client activity is displayed in message box windows.

  3. If the client and service are not able to communicate, see Troubleshooting Tips for WCF Samples.

To run the sample across machines

  1. On the service machine, create a virtual directory named ServiceModelSamples. The Setupvroot.bat script included with the sample can be used to create the disk directory and virtual directory.

  2. Copy the service program files from %SystemDrive%\Inetpub\wwwroot\servicemodelsamples to the ServiceModelSamples virtual directory on the service machine. Be sure to include the files in the \bin directory.

  3. Copy the client script file from the \client folder, under the language-specific folder, to the client machine.

  4. In the script file, change the address value of the endpoint definition to match the new address of your service. Replace any references to "localhost" with a fully-qualified domain name in the address.

  5. In the WSDL file, serviceWsdl.xml, replace any references to "localhost" with a fully-qualified domain name in the address.

  6. Copy the Client.dll library from the \client\bin folder, under the language-specific folder, to a directory on the client machine.

  7. From a command prompt, navigate to that destination directory on the client machine. If using Windows Vista or Windows Server 2008, make sure to run the command prompt as Administrator.

  8. Enter regasm.exe /tlb:CalcProxy.tlb client.dll to register the types with COM. Ensure that path has been set to the folder that contains regasm.exe before you run the command.

  9. Enter gacutil.exe /i client.dll to add the assembly to the Global Assembly Cache. Ensure that path has been set to the folder that contains gacutil.exe before you run the command.

  10. Test that you can access the service from the client machine using a browser.

  11. On the client machine, launch ComCalcClient.vbs.

To clean up after the sample

  • For security purposes, remove the virtual directory definition and permissions granted in the setup steps when you are finished with the samples.

© 2007 Microsoft Corporation. All rights reserved.