There seems to be a lot of confusion regarding SOAP and attachments. Since I've done a lot of research lately on the topic, I thought I'd post some information that may be useful to others.

My goal was to write AXIS services that could accept/send attachments from/to SOAP clients written using the "SOAP Toolkit 3.0" and the "Web Services Enhancements 1.0" (sometimes called the WSDK) (both from Microsoft).

Here I'll roughly describe what I went through to achieve this goal.

-------------------------------

The "Web Services Enhancements 1.0" was easiest. The sample program in...

<WSE-install>\Samples\QuickStart\Clients\Attachments

shows you how to send an "unreferenced" attachment. This is an attachment that is *not* referenced by the soap envelope.

The first thing needed is to add the following code to their EchoAttachment.Echo() method before the "this.invoke()" line.

----------------------------------------------------
// Needed to not confuse Apache AXIS.
this.RequestSoapContext.Path.MustUnderstand = false;
----------------------------------------------------

Without this, a WS-Routing SOAP header with a MustUnderstand value of true will cause AXIS to generate a fault (since it doesn't understand it).

In order to specify the URL of your choice, in AttachmentsClient.Run() method, right after...

EchoAttachment serviceProxy = new EchoAttachment();

add a line like...

----------------------------------------------------
serviceProxy.Url = "http://localhost:8080/axis/services/YourServicePath";;
----------------------------------------------------

This sample shows how to send an attachment but not how to receive one. To receive an unreferenced attachment, after the method call (in AttachmentsClient.cs), you can add lines like...

----------------------------------------------------
if (serviceProxy.ResponseSoapContext.Attachments.Count >= 1)
{
attachment = serviceProxy.ResponseSoapContext.Attachments[0];
...
----------------------------------------------------

So now we should have a C# SOAP client that sends/accepts a DIME attachment and won't confuse AXIS (with its special WS-Routing SOAP header).
(I used Visual Studio 7.0 to build this project)

We now need to write an AXIS service that can receive/send unreferenced attachments. Luckily, this is easy...

In your service, you can use the current MessageContext to iterate over any attachments that were sent to you and also to add any attachments you want in your response.

Here is some sample code that looks for the first received attachment and sends it back to the client.


----------------------------------------------------
org.apache.axis.MessageContext context = org.apache.axis.MessageContext.getCurrentContext();
java.util.Iterator i = context.getMessage().getAttachments();
if (i != null)
{
if (i.hasNext())
{
Object attachmentPartCandidate = i.next();
if (attachmentPartCandidate instanceof org.apache.axis.attachments.AttachmentPart)
{
org.apache.axis.attachments.AttachmentPart attachmentPart = (org.apache.axis.attachments.AttachmentPart) attachmentPartCandidate;

try
{
javax.activation.DataHandler dh = attachmentPart.getDataHandler();

// Do what you will with dh!

// Build up an AttachmentPart to send in the response. For this
// sample, we'll just re-use the one we were sent.
org.apache.axis.Message responseMessage = context.getResponseMessage();
responseMessage.addAttachmentPart(attachmentPart);
}
catch (javax.xml.soap.SOAPException e)
{
// Ignore
}
}
}
}
----------------------------------------------------


----------------------------------------------------
----------------------------------------------------

Now we'll move on to MS SOAP Toolkit 3.0. This toolkit has a lot of machinery. There are both high and low-level APIs for dealing with your SOAP message and attachments.

The low-level attachment client examples are in...

<MSSOAP3.0>\Samples30\Attach\Client\SrSz\WshVbs

These programs are scripts (wscript, vbscript, etc..) that build up the SOAP message directly. They don't require a WSDL.

I hacked on one of them to produce the following script which works with the AXIS sample urn:EchoAttachmentsService (after an AXIS source code change; more on this later).


[Start of samtest.vbs]
------------------------------------------------------------------------------
' I combined parts of GetPicture.vbs and PutPicture.vbs along with some
' code of my own.
Option Explicit

' This is the URL to which messages will be sent.
'Const END_POINT_URL = "http://MSSoapSampleServer/MSSoapSamples30/Attach/Service/SrSz/AspVbs/PutPicture.asp";
Const END_POINT_URL = "http://sbrow1d:9876/axis/services/urn:EchoAttachmentsService";

Dim Connector
Dim Reader
Dim Parser
Dim Serializer
Dim Attachment

Dim ReceivedAttach
Dim RcvdAttachments
Dim Node
Dim NodeList

Dim ScriptPath

Dim Composer
Dim FileAttachment

Dim res

' Create an HTTP connector and set the end point URL.
Set Connector = CreateObject("MSSOAP.HttpConnector30")
Connector.Property("EndPointURL") = END_POINT_URL
Connector.Property("SoapAction") = "http://tempuri.org/Attach/action/Attach.echo";


' Create a file attachment object and set it's FileName property.
Set FileAttachment = CreateObject("MSSOAP.FileAttachment30")
ScriptPath = "D:\\VS.NET\\MSSOAP3.0\\Samples30\\Attach\\Client\\SrSz\\WshVbs\\"
FileAttachment.FileName = ScriptPath & "SamplePicture.jpg"

' Create DIME composer and serializer objects, then initialize the
' serializer with the composer.
Set Composer = CreateObject("MSSOAP.DimeComposer30")
Set Serializer = CreateObject("MSSOAP.SoapSerializer30")
Serializer.InitWithComposer Connector.InputStream, Composer

' Write out the SOAP Envelope and Body start tags.
Serializer.StartEnvelope
Serializer.StartBody


' Start the method element.
Serializer.StartElement "echo"

' Write out the element that references the picture attachment.
' AXIS doesn't seem to care what this element name is.
Serializer.StartElement "Picture"
Serializer.AddAttachmentAndReference FileAttachment
Serializer.EndElement

Serializer.EndElement

' Write out the SOAP Envelope and Body end tags.
Serializer.EndBody
Serializer.EndEnvelope

' Tell the serializer that we are finished providing all message
' content (both the SOAP envelope and all attachments).
Serializer.Finished

'-----------------------------------------------------------
' Create a DimeParser30 object. This object will find the SOAP Envelope
' and any DIME attachments in the request message and make them available
' though the SoapReader30 object.
Set Parser = CreateObject("MSSOAP.DimeParser30")

' Create a SoapReader30 object. This object will provide access to the
' SOAP Evelope contents and any attachments identified by the DimeParser30
' object.
Set Reader = CreateObject("MSSOAP.SoapReader30")
res = Reader.LoadWithParser(Connector.OutputStream, Parser)

Set Node = Reader.RPCParameter("returnqname")

Set Attachment = Reader.GetReferencedAttachment(Node)

' Save the attachment to a file. Indicate that any existing file
' with this can can be replaced.
ScriptPath = "D:\\VS.NET\\MSSOAP3.0\\Samples30\\Attach\\Client\\SrSz\\WshVbs\\"
Attachment.SaveToFile ScriptPath & "ReceivedPicture.jpg", True
------------------------------------------------------------------------------
[End of samtest.vbs]


The tricky part here was extracting the attachment from the response.

As I mentioned, above, getting this to work required changing one line of AXIS source code so let me explain this.

The referenced attachment that AXIS sends out has an "href" attribute in the body that looks something like...

cid:987623414253512151413145151

The actual DIME attachment has an ID that does *not* have the "cid:"; prefix. It appears that the MS SOAP Toolkit 3.0 is confused by this since it is expecting a literal match.

In order to get this to work, I had to change...

org\apache\axis\attachments\AttachmentPart.java

as follows...

public String getContentIdRef() {
// Original version.
//return Attachments.CIDprefix + getContentId();

// The below version allows MSSOAP Tookit 3.0 to work. They get confused because
// the href attribute has something like "cid:1234...."; but the attachment itself
// just has 1234... *without* the cid: prefix.
return getContentId();
}


I compiled just this file and placed its .class file in...

<axis-install>\webapps\axis\WEB-INF\classes\org\apache\axis\attachments

After restarting Tomcat, this altered .class file kicked in and produced responses without the "cid:"; prefix.

With this in place, the samtest.vbs script above worked correctly.

Microsoft seems to use a prefix of "uuid:" but they use it both in the href attribute and in the attachment id whereas
AXIS uses "cid:"; in the href attribute but not in the attachment id.




I'll now move on to the high-level API. The high-level attachment example is in...

<MSSOAP3.0>\Samples30\Attach\Client\Rpc\Cpp

The high-level API dynamically reads a WSDL file and exposes (via COM) interfaces for the SOAP methods described in the WSDL file.

This is kind of clunky since you have to write a lot of code to make the call.

I started by modifying the Attach.wsdl file in this sample to have some new entries.

[Start of modified Attach.wsdl]
-------------------------------------------------------
<?xml version='1.0' encoding='UTF-8' ?>
<!-- Generated 04/22/02 by Microsoft SOAP Toolkit WSDL File Generator, Version 3.00.1122.0 -->
<definitions
name='Attach'
targetNamespace='http://tempuri.org/Attach/wsdl/'
xmlns:wsdlns='http://tempuri.org/Attach/wsdl/'
xmlns:typens='http://tempuri.org/Attach/type/'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:stk='http://schemas.microsoft.com/soap-toolkit/wsdl-extension'
xmlns:dime='http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/'
xmlns:ref='http://schemas.xmlsoap.org/ws/2002/04/reference/'
xmlns:content='http://schemas.xmlsoap.org/ws/2002/04/content-type/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>

<types>
<schema
targetNamespace='http://tempuri.org/Attach/type/'
xmlns='http://www.w3.org/2001/XMLSchema'
xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
elementFormDefault='qualified'>

<import namespace='http://schemas.xmlsoap.org/soap/encoding/'/>
<import namespace='http://schemas.xmlsoap.org/wsdl/'/>
<import namespace='http://schemas.xmlsoap.org/ws/2002/04/reference/'/>
<import namespace='http://schemas.xmlsoap.org/ws/2002/04/content-type/'/>

<complexType name='UnknownBinaryContent'>
<simpleContent>
<restriction base='base64Binary'>
<annotation>
<appInfo>
<!--
You may use one or more of the following elements to describe the binary content:
<content:type value='(URI identifying type)'/>
<content:mediaType value='(MIME media type)'/>
<content:documentType value='(QName of XML document)'/>
-->
<content:mediaType value='application/octet-stream'/>
</appInfo>
</annotation>
</restriction>
</simpleContent>
</complexType>

</schema>
</types>

<message name='Attach.PutPicture'>
<part name='Picture' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.PutPictureResponse'>
</message>

<message name='Attach.echo'>
<part name='returnqname' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.echoResponse'>
<!--
The name here doesn't seem to matter as long as it isn't
returnqname because, if it is, this value appears on the
parameterOrder attribute and because it sees it in both
the input and output portions, it thinks it is an in/out
parameter and that messes things up apparently.
-->
<part name='Sam' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.GetPicture'>
</message>

<message name='Attach.GetPictureResponse'>
<part name='Result' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.PutXml'>
<part name='SampleXml' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.PutXmlResponse'>
</message>

<message name='Attach.GetXml'>
</message>

<message name='Attach.GetXmlResponse'>
<part name='Result' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.PutRecordset'>
<part name='Recordset' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.PutRecordsetResponse'>
</message>

<message name='Attach.GetRecordset'>
</message>

<message name='Attach.GetRecordsetResponse'>
<part name='Result' type='typens:UnknownBinaryContent'/>
</message>

<message name='Attach.PutMultiple'>
<part name='OtherParam' type='xsd:string'/>
</message>

<message name='Attach.PutMultipleResponse'>
</message>

<message name='Attach.GetMultiple'>
<part name='OtherParam' type='xsd:string'/>
</message>

<message name='Attach.GetMultipleResponse'>
</message>

<message name='Attach.PutGetMultiple'>
<part name='OtherParam' type='xsd:string'/>
</message>

<message name='Attach.PutGetMultipleResponse'>
</message>

<portType name='AttachSoapPort'>

<operation name='PutPicture' parameterOrder='Picture'>
<input message='wsdlns:Attach.PutPicture'/>
<output message='wsdlns:Attach.PutPictureResponse'/>
</operation>

<operation name='echo' parameterOrder='returnqname'>
<input message='wsdlns:Attach.echo'/>
<output message='wsdlns:Attach.echoResponse'/>
</operation>

<operation name='GetPicture' parameterOrder=''>
<input message='wsdlns:Attach.GetPicture'/>
<output message='wsdlns:Attach.GetPictureResponse'/>
</operation>

<operation name='PutXml' parameterOrder='SampleXml'>
<input message='wsdlns:Attach.PutXml'/>
<output message='wsdlns:Attach.PutXmlResponse'/>
</operation>

<operation name='GetXml' parameterOrder=''>
<input message='wsdlns:Attach.GetXml'/>
<output message='wsdlns:Attach.GetXmlResponse'/>
</operation>

<operation name='PutRecordset' parameterOrder='Recordset'>
<input message='wsdlns:Attach.PutRecordset'/>
<output message='wsdlns:Attach.PutRecordsetResponse'/>
</operation>

<operation name='GetRecordset' parameterOrder=''>
<input message='wsdlns:Attach.GetRecordset'/>
<output message='wsdlns:Attach.GetRecordsetResponse'/>
</operation>

<operation name='PutMultiple' parameterOrder='OtherParam'>
<input message='wsdlns:Attach.PutMultiple'/>
<output message='wsdlns:Attach.PutMultipleResponse'/>
</operation>

<operation name='GetMultiple' parameterOrder='OtherParam'>
<input message='wsdlns:Attach.GetMultiple'/>
<output message='wsdlns:Attach.GetMultipleResponse'/>
</operation>

<operation name='PutGetMultiple' parameterOrder='OtherParam'>
<input message='wsdlns:Attach.PutGetMultiple'/>
<output message='wsdlns:Attach.PutGetMultipleResponse'/>
</operation>

</portType>

<binding name='AttachSoapBinding' type='wsdlns:AttachSoapPort' >

<stk:binding preferredEncoding='UTF-8'/>
<soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>

<operation name='PutPicture'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.PutPicture'/>
<input>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='Picture'/>
</input>
<output>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</output>
</operation>

<operation name='echo'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.echo'/>
<input>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='returnqname'/>
</input>
<output>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='Sam'/>
</output>
</operation>

<operation name='GetPicture'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.GetPicture'/>
<input>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</input>
<output>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='Result'/>
</output>
</operation>

<operation name='PutXml'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.PutXml'/>
<input>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='SampleXml'/>
</input>
<output>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</output>
</operation>

<operation name='GetXml'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.GetXml'/>
<input>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</input>
<output>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='Result'/>
</output>
</operation>

<operation name='PutRecordset'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.PutRecordset'/>
<input>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='Recordset'/>
</input>
<output>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</output>
</operation>

<operation name='GetRecordset'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.GetRecordset'/>
<input>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</input>
<output>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='Result'/>
</output>
</operation>

<operation name='PutMultiple'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.PutMultiple'/>
<input>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/open-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='OtherParam'/>
</input>
<output>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</output>
</operation>

<operation name='GetMultiple'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.GetMultiple'/>
<input>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='OtherParam'/>
</input>
<output>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/open-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</output>
</operation>

<operation name='PutGetMultiple'>
<soap:operation soapAction='http://tempuri.org/Attach/action/Attach.PutGetMultiple'/>
<input>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/open-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts='OtherParam'/>
</input>
<output>
<dime:message
layout='http://schemas.xmlsoap.org/ws/2002/04/dime/open-layout'
wsdl:required='true'/>
<soap:body
use='encoded'
namespace='http://tempuri.org/Attach/message/'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
parts=''/>
</output>
</operation>

</binding>

<service name='Attach' >
<port name='AttachSoapPort' binding='wsdlns:AttachSoapBinding' >
<soap:address location='http://MSSoapSampleServer/MSSoapSamples30/Attach/Service/Rpc/IsapiCpp/Attach.WSDL'/>
</port>
</service>

</definitions>
-------------------------------------------------------
[End of modified Attach.wsdl]

Just search for "echo" in the file above to see the new entries I introduced to reflect the AXIS sample urn:EchoAttachmentsService.

There were a few tricky parts. See inline comments for more details.

I then modified the OnPutPicture() method in the AttachCliRpcCpp.cpp sample file as follows...

[Start of modified OnPutPicture() method]
-------------------------------------------------------
void CAttachCliRpcCppDlg::OnPutPicture()
{

HRESULT hr;

try
{

// Display the hourglass mouse pointer.
BeginWaitCursor();


// Create a FileAttachment30 object.
IFileAttachmentPtr pFileAttachment;
hr = pFileAttachment.CreateInstance(__uuidof(FileAttachment30));
if( FAILED(hr) ) RaiseError(L"Cannot create MSSOAP.FileAttachment30 object.", hr);


// Set the file attachment object's file name property to the
// name of the file that will be sent as an attachment.
CString FileName = m_AppPath + _T("\\SamplePicture.jpg");
pFileAttachment->FileName = _bstr_t(FileName);


// Perform the PutPicture operation.

EXCEPINFO excepinfo;
DISPID dispid;
DISPPARAMS params;
const int CARGS = 1; // One argument.
_variant_t args[CARGS];
_variant_t result;
//WCHAR *pName = L"PutPicture";
WCHAR *pName = L"echo";
unsigned int uArgErr;

// Use this to specify your own SOAP URL.
m_pSoapClient->ConnectorProperty["EndPointURL"] = _variant_t("http://sbrow1d:9876/axis/services/urn:EchoAttachmentsService";);

// Get id of "PutPicture" method.
hr = m_pSoapClient->GetIDsOfNames(
IID_NULL,
&pName,
1,
LOCALE_SYSTEM_DEFAULT,
&dispid);
//if( FAILED(hr) ) RaiseError(L"Cannot get id of PutPicture.", hr);
if( FAILED(hr) ) RaiseError(L"Cannot get id of echo.", hr);

excepinfo.wCode = 0;
excepinfo.wReserved = 0;
excepinfo.bstrSource = 0;
excepinfo.bstrDescription = 0;
excepinfo.bstrHelpFile = 0;
excepinfo.dwHelpContext = 0;
excepinfo.pvReserved = 0;
excepinfo.pfnDeferredFillIn = 0;
excepinfo.scode = 0;

params.cArgs = CARGS;
params.cNamedArgs = 0;
params.rgdispidNamedArgs = 0;
params.rgvarg = args;

// File attachment object argument. The type will be set to VT_DISPATCH.
args[0] = (IDispatch*)pFileAttachment;

hr = m_pSoapClient->Invoke(
dispid, // ID of PutPicture
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&params,
&result, // Expect return value.
&excepinfo,
&uArgErr);
if( FAILED(hr) ) RaiseError(L"PutPicture failed.", hr, excepinfo, params, uArgErr);

// Return value is expected to be an IDispatch interface to an
// ReceivedAttachment30 object.
if( result.vt != VT_DISPATCH ) RaiseError(L"echo did not return an object.");

// Get an IReceivedAttachment interface pointer for the return value.
IReceivedAttachmentPtr pReceivedAttachment;
hr = result.pdispVal->QueryInterface(&pReceivedAttachment);
if( FAILED(hr) ) RaiseError(L"echo did not return an IReceivedAttachment interface", hr);

// Save the picture content to a file.
FileName = m_AppPath + "\\ReceivedPicture.jpg";
pReceivedAttachment->SaveToFile(_bstr_t(FileName), VARIANT_TRUE);

// Remove the hourglass mouse pointer.
EndWaitCursor();


// Display an success message.
MessageBox("Success!");

}
catch( _com_error Error )
{

// Remove the hourglass mouse pointer.
EndWaitCursor();

// Display an error message.
DisplayError(_T("Cannot put picture."), Error);

}

}
-------------------------------------------------------
[End of modified OnPutPicture() method]

Mostly the changes needed were...

- Call "echo" instead of "PutPicture"
- Specify URL of my choice.
- Extract the returned attachment (grabbed that code from the OnGetPicture() method)

Build the project, run it, and click the Put Picture button to exercise this code.

This worked for me but, again, only after tweaking AXIS to not put the "cid:"; prefix on outgoing attachment references.


[Wrap up]
------------------------------------------------------

I'll post a short mail to the SOAP developers list so they know about the code change I had to make.

I'm still waiting for a tool what will take a WSDL file that uses the DIME extensions and cranks out a SOAP client that automatically handle attachments. AXIS could do this now. All of the infrastructure is there. Hopefully a future release will add this support.

I hope this posting will be of help to others. I know it would've saved me a lot of research.

Thanks

Sam Brow

Reply via email to