Using UpdateListItems in C++

From: Miguel (Miguel_at_noemail.noemail)
Date: 05/06/04


Date: Thu, 6 May 2004 08:30:23 -0700

I'm trying to use UpdateListItems in am unmanaged C++
application. It works when used from a C# application but
in a C++ application the XML that specifies the update is
escaped ('<' are converted to '&lt', etc.). While
debugging this I noticed that the problem was in atlsoap.h
in the function
inline HRESULT AtlGenXMLValue<wchar_t *>(IWriteStream
*pStream, wchar_t **pVal). This function escaped the
stream that it copies. As a test I overloaded this
function with the following function that merely does a
simply copy of the stream and everything works:

inline HRESULT AtlGenXMLValue(IWriteStream *pStream, BSTR
*pVal)
{
        if ((pStream == NULL) || (pVal == NULL))
        {
                return E_INVALIDARG;
        }

        //
        // delegate to CWriteStreamHelper
        //
        CWriteStreamHelper s(pStream);

        return (s.Write(*pVal) == TRUE ? S_OK : E_FAIL);
}

Is this a bug or by design? If it's by design, how do I
get around having the XML escapes without having to modify
the soap header?

Here is the sample code that I'm using.

void TestUpdateDocumentMetadata()
{
    Lists::CLists lists;
    CNTLMAuthObject authCurrentUser;
    lists.m_socket.AddAuthObj(_T("NTLM"),
&authCurrentUser);
    lists.m_socket.NegotiateAuth(true);

    _bstr_t updates;
    updates += "<Batch OnError=\"Continue\"
PreCalc=\"TRUE\" ListVersion=\"0\">";
    updates += "<Method ID='1' Cmd='Update'>";
    updates += "<Field Name='ID'>9</Field>";
    updates += "<Field
Name='FileRef'>http://myserver/mysite/mydoclibrary/pic.bmp<
/Field>";
    updates += "<Field
Name='MyColumn'>data1</Field>";
    updates += "<Field
Name='MyColumn2'>data2</Field>";
    updates += "</Method>";
    updates += "</Batch>";

    _bstr_t results;
    if (!CheckError(lists.UpdateListItems(_bstr_t
("mydoclibrary"), updates, results.GetAddress())))
        return;

    printf("%s\n", (char*) results);
}

Miguel