Microsoft KB Archive/908574

= How to add SOAP client functionality to native Win32 applications by using managed SOAP classes in Visual Studio .NET =

Article ID: 908574

Article Last Modified on 4/19/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft Visual Studio .NET 2003 Professional Edition
 * Microsoft Visual Studio .NET 2003 Enterprise Architect
 * Microsoft Visual Studio .NET 2003 Enterprise Developer
 * Microsoft Visual Studio .NET 2003 Academic Edition
 * Microsoft Visual Studio .NET 2002 Professional Edition
 * Microsoft Visual Studio .NET 2002 Enterprise Architect
 * Microsoft Visual Studio .NET 2002 Enterprise Developer
 * Microsoft Visual Studio .NET 2002 Academic Edition

-





INTRODUCTION
This article describes how to add SOAP client functionality to native Win32 applications by using managed SOAP classes.



MORE INFORMATION
This method is based on exposing Microsoft .NET Framework components to the Microsoft Component Object Model (COM). To access managed classes that are generated by using this method, do not use only the COM IDispatch interface from .NET Framework–based applications. Also use the IDispatch interface from all applications that are not based on the .NET Framework but use COM objects.

To use managed SOAP classes in native code, follow these steps:  Use the Wsdl.exe utility to create a managed proxy class. To do this, open the Microsoft Visual Studio .NET 2003 Command Prompt window, and then type the following command:

WSDL http://apps.gotdotnet.com/QuickStart/HelloWorld/HelloWorld.asmx?WSDL

 Create a new Microsoft Visual C# Class Library project. To do this, follow these steps:  Start Visual Studio .NET 2003. On the File menu, click New, and then click Project. Click Visual C# Projects, and then click Class Library. In the Name box, type CSharpProxy, and then click OK.</ol> </li>  Replace the code in the Class1.cs file with the code that you generated in step 1. The code is similar to the following code sample. //-- // //    This code was generated by a tool. //    Runtime Version: 1.1.4322.2032 // //    Changes to this file may cause incorrect behavior and will be lost if //     the code is regenerated. // //--

// // This source code was auto-generated by wsdl, Version=1.1.4322.2032. // using System.Diagnostics; using System.Xml.Serialization; using System; using System.Web.Services.Protocols; using System.ComponentModel; using System.Web.Services;

/// [System.Diagnostics.DebuggerStepThroughAttribute] [System.ComponentModel.DesignerCategoryAttribute(&quot;code&quot;)] [System.Web.Services.WebServiceBindingAttribute(Name=&quot;HelloWorldSoap&quot;, Namespace=&quot;http://tempuri.org/&quot;)] public class HelloWorld : System.Web.Services.Protocols.SoapHttpClientProtocol { ///    public HelloWorld { this.Url = &quot;http://apps.gotdotnet.com/QuickStart/HelloWorld/HelloWorld.asmx&quot;; }   ///     [System.Web.Services.Protocols.SoapDocumentMethodAttribute(&quot;http://tempuri.org/SayHelloWorld&quot;, RequestNamespace=&quot;http://tempuri.org/&quot;, ResponseNamespace=&quot;http://tempuri.org/&quot;, Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public string SayHelloWorld { object[] results = this.Invoke(&quot;SayHelloWorld&quot;, new object[0]); return ((string)(results[0])); }   ///     public System.IAsyncResult BeginSayHelloWorld(System.AsyncCallback callback, object asyncState) { return this.BeginInvoke(&quot;SayHelloWorld&quot;, new object[0], callback, asyncState); }   ///     public string EndSayHelloWorld(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); } } </li> In Solution Explorer, right-click Class1.cs, and then click Rename.</li> Type HelloWorld.cs, and then press ENTER.</li> You must create a public interface and class to wrap the WSDL-generated code and to delegate the call. To do this, make changes in the proxy-generated class to make sure that all classes will be exposed in COM. To do this, follow these steps: <ol style="list-style-type: lower-alpha;">  Add the following using statement to the proxy-generated class: using System.Runtime.InteropServices; </li>  Add the following code example to the end of the HelloWorld class. public interface IHelloWorld {   string SayHelloWorld; }

[ComVisible(true)]   // By default, this value is true. However, this line of code is    // included for documentation purposes. public class WrapHelloWorld : IHelloWorld {   public WrapHelloWorld {   }    public string SayHelloWorld {       HelloWorld ws = new HelloWorld; return ws.SayHelloWorld; } } </li> Press CTRL+SHIFT+B to build the solution.</li></ol> </li>  As soon as the Visual C# solution is built, you must register the DLL with COM. To do this, follow these steps: <ol style="list-style-type: lower-alpha;"> Open the Visual Studio .NET 2003 Command Prompt window.</li> Move to the folder that contains the solution DLL.</li> Type the following command, and then press ENTER:

RegAsm.exe CSharpProxy.dll /tlb:CSharpProxy.tlb

</li></ol>

You can now use the generated CSharpProxy.tlb file in native code. The following code example illustrates how to use the CSharpProxy.tlb file in Visual C++.
 * 1) include &quot;stdafx.h&quot;
 * 2) import &quot;CSharpProxy.tlb&quot; raw_interfaces_only
 * 3) include
 * 4) include <atlbase.h>

using namespace CSharpProxy; using namespace std;

int _tmain(int argc, _TCHAR* argv[]) {   HRESULT hr = CoInitialize(NULL); BSTR Val; IHelloWorldPtr ptrHW (__uuidof(WrapHelloWorld)); ptrHW>SayHelloWorld(&Val);

CW2A szResponse(Val); cout << szResponse << endl; ::SysFreeString(Val); CoUninitialize; return 0; } </li></ol>

<div class="references_section">