locked
Calling C# webservice from Visual C++ 6 using SOAP RRS feed

  • Question

  • Iam trying to call a C# DotNet 2003 webservice from Visual C++ 6 app (used win32 console, mfc, atl_mfc dll) using Soap toolkit 3. The webservice takes a String input parameter and returns a String. The input parameter I pass through C++ is always recieved as NULL in C# webservice while the output is working fine and it is returned back in C++.
    I have even tried with wsp wizard using atl_mfc dll and vb GUI but input always failed. It didn't give any error either. It will give an error when I output, input parameter as it is without appending to a string, then it will say Invalid pointer error in C++ app. Plz anybody can help in this regard. A bundle of thanks.

    My C# webservice code is as, it is a simple ASP.NET web service generated through VS.NET 2003:
    [WebMethod]
    public string TestMethod(string input)
    {
     return "Hello World"+input;
    }

    My C++ code is as:
       #include <stdio.h>

       #import "msxml4.dll"
       using namespace MSXML2;
     
       #import "C:\Program Files\Common Files\MSSoap\Binaries\MSSOAP30.dll" \
             exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")
       using namespace MSSOAPLib30;

     

       ISoapSerializerPtr Serializer;
       ISoapReaderPtr Reader;
       ISoapConnectorPtr Connector;

       // Connect to the service
       Connector.CreateInstance(__uuidof(HttpConnector30));
       Connector->Property["EndPointURL"] = "http://localhost/WS/Service1.asmx";

       Connector->Connect();

       // Begin message
       Connector->Property["SoapAction"] = "http://tempuri.org/TestMethod";
       Connector->BeginMessage();

       // Create the SoapSerializer
       Serializer.CreateInstance(__uuidof(SoapSerializer30));

       // Connect the serializer to the input stream of the connector
       Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

       // Build the SOAP Message
       Serializer->StartEnvelope("","","");
       Serializer->StartBody("");
       Serializer->StartElement("TestMethod","http://tempuri.org/TestMethod","","m");
       Serializer->StartElement("input","","","");
       Serializer->WriteString("input");
       Serializer->EndElement();
       Serializer->EndElement();
       Serializer->EndBody();
       Serializer->EndEnvelope();
      
       // Send the message to the web service
       Connector->EndMessage();     

       // Let us read the response
       Reader.CreateInstance(__uuidof(SoapReader30));

       // Connect the reader to the output stream of the connector
       Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), "");

       // Display the result
       printf("Answer: %s\n", (const char *)Reader->RpcResult->text);

       _bstr_t res = Reader->RpcResult->text;

     

    Saturday, August 19, 2006 2:25 PM

Answers

  • Yes i realized that but i just queried you may be you know something. Atlast I was able to solve my problem. I successfully called VS.Net 2003 C# web service from VC 6 using MFC WinInet classes. I created and passed soap message using WinInet without using soap toolkit. It successfully accepted and return value. Anybody interested?

     

    Wednesday, August 30, 2006 6:27 PM

All replies

  • Moving from Data Access and Storage
    Saturday, August 19, 2006 5:33 PM
    Moderator
  • Can u ellaborate it a bit? Plz help if u can?

     Thanx a lot for ur time and effort.

     

    //Moving from Data Access and Storage

    Thursday, August 24, 2006 2:03 PM
  • I just said that I moved your post from Data Access forum because here (ASP.NET Web Services and XML Serialization) is a better place for posting this kind of question.
    Thursday, August 24, 2006 5:23 PM
    Moderator
  • Yes i realized that but i just queried you may be you know something. Atlast I was able to solve my problem. I successfully called VS.Net 2003 C# web service from VC 6 using MFC WinInet classes. I created and passed soap message using WinInet without using soap toolkit. It successfully accepted and return value. Anybody interested?

     

    Wednesday, August 30, 2006 6:27 PM
  • We need to call .NET web services from within VC++ 6.0 too and would like to know if you have been able to resolve how to do this?

     

    Regards,

    Jim

    Monday, September 25, 2006 3:43 PM
  • MFC provides wrapper classes around WinInet API. These classes simplify the task of writing HTTP/FTP client applications. Following are the eight steps required to send a HTTP request using MFC WinInet classes:
    1. Create an instance of CInternetSession class. This begins an HTTP session.
    2. Call CInternetSession::GetHttpConnection to get an instance of CHttpConnection. Pass the server and HTTP port to this method, and it establishes a connection to an HTTP server.
    3. Open an HTTP request using CHttpConnection::OpenRequest. Pass the rest of the URL (except server name), the HTTP method (GET/POST/...) to this method, and it returns a CHttpFile object.
    4. Optionally, call CHttpFile::AddRequestHeaders to supply any request headers.
    5. Call CHttpFile::SendRequest to actually send the request and get the response back.
    6. Use CHttpFile::QueryInfoStatusCode to find out if the HTTP request succeeded.
    7. On success, use pHttpFile->Read to read the response bytes.
    8. Finally, call CHttpFile::Close and CHttpConnection::Close.

    #include <afxinet.h>

    static const TCHAR* g_lpszSOAPRequest =   
    _T("<soap:Envelope "
        "xmlns:n='urn:xmethods-WebServiceMethod' "
        "xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' "
        "xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' "
        "xmlns:xs='http://www.w3.org/2001/XMLSchema' "
        "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> "
        "<soap:Body soap:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'> "
        "  <n:RecieveData> "
        "     <input xsi:type='xs:string'>input meessage</input> "
        "  </n:RecieveData> "
       "</soap:Body> "
    "</soap:Envelope>");

    #define CHUNK_SIZE      2048
      
    void CallWS()
    {
       try
       {
          CInternetSession httpSession(_T("Web Service Client"),
                               1,
                               INTERNET_OPEN_TYPE_PRECONFIG,
                               NULL,
                               NULL,
                               INTERNET_FLAG_DONT_CACHE);
          

          Server URL and Port required
          CHttpConnection* pHttpConnection =
                                  httpSession.GetHttpConnection(_T("localhost"),
                                     INTERNET_FLAG_NO_AUTO_REDIRECT,
                                     80, NULL, NULL);

         URL path (except server name)

          CHttpFile* pHttpFile             =
                                  pHttpConnection->OpenRequest
                                  (_T("POST"),
                                     _T("EPWS/Service1.asmx"),
                                     NULL, 1, NULL, NULL,
                                     INTERNET_FLAG_KEEP_CONNECTION |
                                     INTERNET_FLAG_EXISTING_CONNECT |
                                     INTERNET_FLAG_DONT_CACHE |
                                     INTERNET_FLAG_RELOAD);

          CString strSOAPReq(g_lpszSOAPRequest);
          DWORD dwRewLen = strSOAPReq.GetLength();
          CString strHeaders;
          strHeaders.Format(_T("Content-Type: text/xml; charset=utf-8\nContent-Length:%d"), dwRewLen);
          pHttpFile->AddRequestHeaders(strHeaders);

          pHttpFile->SendRequest(NULL, 0, (LPVOID)(LPCTSTR)strSOAPReq, dwRewLen);

          DWORD dwStatucCode = HTTP_STATUS_OK;

          pHttpFile->QueryInfoStatusCode(dwStatucCode);

          if(dwStatucCode == HTTP_STATUS_OK)
          {
             CString strResponse;
             TCHAR szBuf[CHUNK_SIZE] = {0};
             UINT nBytesRead;

             do
             {
                nBytesRead = pHttpFile->Read((void*) szBuf, CHUNK_SIZE);
                strResponse += szBuf;
                if(nBytesRead < CHUNK_SIZE)
                   break;
             }while(nBytesRead == CHUNK_SIZE);

             AfxMessageBox(strResponse);
          }
          else
          {
             //Error handling
          }

          if(pHttpFile)
          {
             pHttpFile->Close();
             delete pHttpFile;
             pHttpFile = NULL;
          }

          if(pHttpConnection)
          {
             pHttpConnection->Close();
             delete pHttpConnection;
             pHttpConnection = NULL;
          }

       }
       catch(CInternetException* exp)
       {
          TCHAR lpszErrorMsg[MAX_PATH+2];
          exp->GetErrorMessage(lpszErrorMsg, MAX_PATH);
          AfxMessageBox(lpszErrorMsg);
       }
    }

     

    • Proposed as answer by hsx_solon Saturday, July 24, 2010 3:08 AM
    Tuesday, September 26, 2006 4:50 AM
  • I have included the web service in my project using the Add Web reference option. When i have done this, it is creating a Proxy class for the web service. Now am instantiating the COM object, object to the proxy class, By using the proxy class object am calling the function which is inside the web service. This function will take a date argument as inout and returns a character array. The date is in xsd:dateTime format in the wsdl file. So i have converted my date into a BSTR one and i have passed it in the function. the program is compiling fine. When i tried to Run the program it's showing "SOAPCLIENT_SOAP_FAULT". Why is it so?

    But when am trying to access another function (which does not required any input arguments, need only one return character array) it is working fine.

    How to solve this problem.  It will be very much helpful if any one help me in solving this problem, Since it's very urgent for me.

    Am attaching the sample code

    CoInitialize(NULL);

    {

    className *obj;

    Character Array res;

    CString startdate=_T("01-jan-2006");

    BSTR fromDate = startdate.AllocSysString();

    HRESULT hr=obj->get_details(fromDate,&res);

    if (FAILED(hr))

    {

    AfxMessageBox(GetSoapError(static_cast<CSoapSocketClientT<> *>(obj)),MB_ICONSTOP);

    AfxMessageBox(_T("not working"));

    }

    else

    {

    AfxMessageBox(_T("working"));

    }

    }

    CoUninitialize();

    Thanks and Regards,

    Ajith Sivakumar

     

    Saturday, October 14, 2006 3:50 PM
  • Hello, i would be interested to know how you did it. I would like to tell me the thought of the steps in your coding. Plz upload it or send it. 

    Thank you as Thnx

    Mr. Leonidas Fengos


    Mr. Leonidas Fengos Object Oriented Programmer as Software Engineer
    Sunday, August 7, 2011 10:55 AM
  • Hello Arslan.Ahmed, i'm with de same problem, please upload or send your conding for us
    Tks, Mateus Caires
    Tuesday, August 16, 2011 8:40 PM