locked
I need to call a C# web service from a VB6 client RRS feed

  • Question

  • There is this old VB6 program that is running in my company. And there is this new web service in C# (.Net 2.0 using Visual Studio 2005) that I have created. I need that VB6 program to make a call to the web service.

    1. Using the wsdl.exe, I create a proxy file - say, TransparancieCalcEngineProxy.cs, which can be used by clients. When I try to use this proxy file from a .Net client (another C# program, for example), the invocation of the web service works fine.

    2. In order to call the web service from the VB6 program, this is what I am trying to do - I create a .Net project in Visual Studio 2005 of type "C# - Class Library" and I name it "TransparencyCalcEngineConsumerDll". I copy paste the proxy file TransparancieCalcEngineProxy.cs into a folder in this new class library project, so this proxy file is now part of the class library. Note - while there might be people saying "this is not the proper way to do this ... this proper way is .....", I appreciate all comments on this aspect and will learn from them, but my final requirement from this post is still how to invoke this .Net class library from VB6.

    3. I create an interface called Interface1 and a class called Class1 in the project WebServiceConsumerDll. Since this is only a test, the codes are pretty simple and r given below:

    Note - The GUIDs have been taken from some article from the internet but I will generate some GUID later when the code actually works. Though I dno't know exactly, I have read that .Net provides some GUID generator tool and I will use that.

    ***************************************** Interface1.cs START ************************

    using System;

    using System.Runtime.InteropServices;

    namespace TransparencyCalcEngineConsumerDll

    {

    [ComVisible(true), GuidAttribute("137AD71F-4657-4362-B9E4-C6D734F1F530")]

    [InterfaceType(ComInterfaceType.InterfaceIsDual)]

    public interface Interface1

    {

    String function1();

    long function2();

    }

    }

    ***************************************** Interface1.cs END ************************

    ******************************** Class1.cs START ******************************

    using System;

    using System.Runtime.InteropServices;

    namespace TransparencyCalcEngineConsumerDll

    {

    [ComVisible(true), GuidAttribute("89BB4535-5A89-43a0-89C5-19A4697E5C5C")]

    [ProgId("SomeNameProject.SomeNameClass1")]

    [ClassInterface(ClassInterfaceType.None)]

    public class Class1 : Interface1

    {

    public String function1()

    {

    //This is code that is calling the web service proxy .... ignore the logic as the same code works perfectly from a .Net
    // windows client

    WSNamespaceTransparantie.ParameterContainer[] listOfParameters = new WSNamespaceTransparantie.ParameterContainer[3];

    WSNamespaceTransparantie.ParameterContainer paramContainer = new WSNamespaceTransparantie.ParameterContainer();

    paramContainer.ParameterName = WSNamespaceTransparantie.EnumParamNames.ProvisieGrondslag;

    paramContainer.ParameterValue = "2000";

    listOfParameters[0] = paramContainer;

    paramContainer = null;

    paramContainer = new WSNamespaceTransparantie.ParameterContainer();

    paramContainer.ParameterName = WSNamespaceTransparantie.EnumParamNames.Product;

    paramContainer.ParameterValue = "Generic TAS Product 1";

    listOfParameters[1] = paramContainer;

    paramContainer = null;

    paramContainer = new WSNamespaceTransparantie.ParameterContainer();

    paramContainer.ParameterName = WSNamespaceTransparantie.EnumParamNames.SubProduct;

    paramContainer.ParameterValue = "Generic TAS Sub - Product 1";

    listOfParameters[2] = paramContainer;

    paramContainer = null;

    WSNamespaceTransparantie.Service service = new WSNamespaceTransparantie.Service();

    WSNamespaceTransparantie.InputObjectTAS tasObj = new WSNamespaceTransparantie.InputObjectTAS();

    tasObj.ServiceConsumer = WSNamespaceTransparantie.EnumServiceConsumer.TAS;

    tasObj.ListOfParameters = listOfParameters;

    WSNamespaceTransparantie.OutputObjectGeneric outObj = service.calculateCommission_returnGeneric(tasObj);

    String returnVal = null;

    //Do a dummy and just concatenate everything in a string for now and return it

    foreach (WSNamespaceTransparantie.ParameterContainer_o p in outObj.ListOfParameters)

    {

    returnVal += p.ParameterName + " = " + p.ParameterValue + " ||| ";

    }

    return returnVal;

    }

    public long function2()

    {

    return 100; //dummy code

    }

    }

    }

    ******************************** Class1.cs END******************************

    In the project properties of TransparencyCalcEngineConsumerDll, in the Application --> Assembly Information, I specify the "Make Assembly COM-visible" check box as true. I do NOT check the checkbox for "Register for COM interop" in the BUILD tab of the project properties.

    I build my project. I get a TransparencyCalcEngineConsumerDll.dll file in the bin/debug folder.

    I run the following command from the .Net command prmopt : 

    regasm /tlb /codebase TransparencyCalcEngineConsumerDll.dll

    tlbexp TransparencyCalcEngineConsumerDll.dll (this gives me TransparencyCalcEngineConsumerDll.tlb file in the same folder)

    4. I open up a new project in VB6. I add reference to the .tlb file I have just created. Then I write the code in a button click in the form (just for testing):

    dim obj as Object
    Set obj = CreateObject("SomeNameProject.SomeNameClass1")

    Result:
    Firstly the call failed saying "this is not a proper assembly" ... then I registered / unregistered / nonsense a couple of times without doing anything new and suddenly the error changed to "could not locate TransparencyCalcEngineConsumerDll or one of its referenced components". This clearly shows that the VB6 is trying to do something with the TransparencyCalcEngineConsumerDll component ..... coz the createobject is actually done for "SomeNameProject.SomeNameClass1". There is no problem with just keeping the .tlb in my references, coz if I comment out the line which does the CreateObject then the execution of the project is fine .... of course it doesn't do anything but it doesn't generate any runtime error either.

    So what am I doing wrong???

    Many thanks!

    Sriram Ranganathan


    Wednesday, September 17, 2008 9:05 AM

Answers

  • Your strategy of wrapping the web service calls in an assembly that can be called from COM seems to be sound. I don't see an obvious reason for the code to fail.

    That may be because I'm not an expert in COM Interop. You will find more of those experts in the Common Language Runtime forum.
    John Saunders | Use File->New Project to create Web Service Projects
    Wednesday, September 17, 2008 10:07 AM
    Moderator