File Attachment in C++

Nilay Hazra <[email protected]> Thu, 4 Sep 2003 18:06:45 +0530
Newsgroups gmane.comp.windows.devel.soap.general
Message-ID <[email protected]>
Hi,
I'm using MS SOAP Toolkit 3.0 and trying to write a client application =
and a service using VC++ 6.0 for uploading a XML file to the server.

For the client application, I'm using the following code. Here I'm =
calling the service method "ProcessAttachment" (which takes the =
attachment (MSSOAPLib30.IAttachment) as the first parameter and the file =
name (BSTR) as the second parameter).

...
void UploadFile()
{
  printf(_T("\nStart\n"));
  USES_CONVERSION;

  CComPtr<ISoapClient> spSOAPClient;
  HRESULT hr =3D spSOAPClient.CoCreateInstance(CLSID_SoapClient30);
  CHECK_HR(hr);

  printf(_T("\nCreate Client Succeeded\n"));

  hr =3D spSOAPClient->MSSoapInit(_bstr_t(g_lpszWSDL_URL), L"", L"", =
_bstr_t(g_lpszWSML_URL));
            // g_lpszWSDL_URL, g_lpszWSML_URL declared somewhere
  CHECK_HR(hr);

  printf(_T("\nInit Client Succeeded\n"));

  CComPtr<IFileAttachment> spFileAttachIn;
  hr =3D spFileAttachIn.CoCreateInstance(CLSID_FileAttachment30);
  CHECK_HR(hr);

  hr =3D spFileAttachIn->put_FileName(_bstr_t(g_lpszFileName)); // =
g_lpszFileName declared somewhere
  CHECK_HR(hr);

  //  Call the Web Service method
  WCHAR *pwcMethodName =3D L"ProcessAttachment";
  DISPID dispidFn =3D 0;
  hr  =3D spSOAPClient->GetIDsOfNames(IID_NULL, &pwcMethodName, 1,=20
    LOCALE_SYSTEM_DEFAULT, &dispidFn);
  CHECK_HR(hr);

  unsigned int uArgErr;
  VARIANT varg[2];
  varg[0].vt =3D VT_DISPATCH;
  varg[0].pdispVal =3D spFileAttachIn;
  varg[1].vt =3D VT_BSTR;
  varg[1].bstrVal =3D _bstr_t("xyz.xml");
=20
  DISPPARAMS params;
  params.cArgs =3D 2;
  params.rgvarg =3D varg;
  params.cNamedArgs    =3D 0;
  params.rgdispidNamedArgs =3D NULL;
  _variant_t result;
  uArgErr =3D -1;

  EXCEPINFO excepInfo;
  memset(&excepInfo, 0, sizeof(excepInfo));
  hr  =3D spSOAPClient->Invoke(dispidFn, IID_NULL, =
LOCALE_SYSTEM_DEFAULT,=20
    DISPATCH_METHOD, &params, &result, &excepInfo, &uArgErr);
printf(_T("%s\n"), W2A(spSOAPClient->FaultString));
  CHECK_HR(hr);
 =20
  return;
}
...

For the service, I'm using the following code.
...
STDMETHODIMP CUpload::ProcessAttachment(VARIANT fileData, BSTR fileName)
{
 CComPtr<IReceivedAttachment> spReceivedAttachment;
  HRESULT hr =3D =
spReceivedAttachment.CoCreateInstance(L"MSSOAPLib30.IReceivedAttachment")=
;
  // if (FAILED(hr)) return error

 IReceivedAttachment* pIX =3D NULL;
 if(fileData.vt=3D=3DVT_DISPATCH) {
  hr =3D (fileData.pdispVal)->QueryInterface(IID_IReceivedAttachment, =
(void **)&pIX);
  // if (FAILED(hr)) return error

  spReceivedAttachment =3D pIX;
  spReceivedAttachment->SaveToFile(fileName, true);
  return S_OK;
 }
 else
  // Not OK, return error
}
...

I've also generated WSDL file using WSDL generator tool provided with =
the SOAP toolkit. Some part of it (which maps the data type) is in the =
following.
...
<message name=3D'Upload.ProcessAttachment'>
  <part name=3D'fileData' type=3D'xsd:anyType'/>
  <part name=3D'fileName' type=3D'xsd:string'/>
 </message>
...

When I'm running the client application, I'm getting the following Fault =
String "SoapMapper:Converting data for SoapMapper failed inside the =
typemapper" from the Invoke method.

How can I fix it? Please help.

nhazra