gSoap EWS “Error 500: Internal Server Error”

2020-05-06 12:46发布

问题:

I have some problems with ews(gSoap).

I have next code:

ExchangeServiceBindingProxy *proxy = new ExchangeServiceBindingProxy(endpoint.c_str());

soap *pSoap = proxy->soap;
pSoap->userid = "Ivan1";
pSoap->passwd = "1";
pSoap->ntlm_challenge = "";
pSoap->authrealm = "Ursa-Minor";

pSoap->ssl_flags = SOAP_SSL_NO_AUTHENTICATION;
pSoap->keep_alive = true;   
pSoap->mode = SOAP_IO_KEEPALIVE;

//get root folder ID
ns3__DistinguishedFolderIdType *dfit = new ns3__DistinguishedFolderIdType();
dfit->Id = ns3__DistinguishedFolderIdNameType__inbox;

//set the props that we want to retrieve
ns3__FolderResponseShapeType *frst = new ns3__FolderResponseShapeType();
frst->BaseShape = ns3__DefaultShapeNamesType__AllProperties;

//get folder
ns1__GetFolderType *gftRoot = new ns1__GetFolderType();
gftRoot->FolderIds = new ns3__NonEmptyArrayOfBaseFolderIdsType();
gftRoot->FolderIds->__size_NonEmptyArrayOfBaseFolderIdsType = 1;
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType = new __ns3__union_NonEmptyArrayOfBaseFolderIdsType();
gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->union_NonEmptyArrayOfBaseFolderIdsType.DistinguishedFolderId = dfit;
gftRoot->FolderIds = (ns3__NonEmptyArrayOfBaseFolderIdsType*)dfit;
gftRoot->FolderShape = frst;
__ns1__GetFolderResponse response;

int ret = proxy->GetFolder(gftRoot, response);

I`m using OpenSSL and NTLM libs(WITH_OPENSSL, WITH_NTLM).

As a resault gSoap generates this SOAP:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope 
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:ns3="http://schemas.microsoft.com/exchange/services/2006/types" 
xmlns:ns1="http://schemas.microsoft.com/exchange/services/2006/messages">
<SOAP-ENV:Header>
<ns3:RequestServerVersion SOAP-ENV:mustUnderstand="1" Version="Exchange2010">
</ns3:RequestServerVersion>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:GetFolder xsi:type="ns1:GetFolderType">
<ns1:FolderShape>
<ns3:BaseShape>AllProperties</ns3:BaseShape>
</ns1:FolderShape>
<ns1:FolderIds Id="inbox" xsi:type="ns3:DistinguishedFolderIdType"> </ns1:FolderIds>
</ns1:GetFolder>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Response from server:

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.0
Set-Cookie: exchangecookie=88bb510ab2ef4191a42c6cf9aada1614; expires=Fri, 24-Oct-2014 09:45:45 GMT; path=/; HttpOnly
X-EwsPerformanceData: RpcC=0;RpcL=0;LdapC=0;LdapL=0;
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Thu, 24 Oct 2013 09:45:45 GMT
Connection: close

5d0
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <s:Fault>
            <faultcode xmlns:a="http://schemas.microsoft.com/exchange/services/2006/types">a:ErrorSchemaValidation</faultcode>
            <faultstring xml:lang="en-US">The request failed schema validation: The xsi:type attribute value 'http://schemas.microsoft.com/exchange/services/2006/types:DistinguishedFolderIdType' is not valid for the element 'http://schemas.microsoft.com/exchange/services/2006/messages:FolderIds', either because it is not a type validly derived from the type in the schema, or because it has xsi:type derivation blocked.</faultstring>
            <detail>
                <e:ResponseCode xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">ErrorSchemaValidation</e:ResponseCode>
                <e:Message xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">The request failed schema validation.</e:Message>
                <t:MessageXml xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
                    <t:LineNumber>2</t:LineNumber>
                    <t:LinePosition>519</t:LinePosition>
                    <t:Violation>The xsi:type attribute value 'http://schemas.microsoft.com/exchange/services/2006/types:DistinguishedFolderIdType' is not valid for the element 'http://schemas.microsoft.com/exchange/services/2006/messages:FolderIds', either because it is not a type validly derived from the type in the schema, or because it has xsi:type derivation blocked.
                    </t:Violation>
                </t:MessageXml>
            </detail>
        </s:Fault>
    </s:Body>
</s:Envelope>

As you can see, the problem is in line

<ns1:FolderIds Id="inbox" xsi:type="ns3:DistinguishedFolderIdType"

Server don`t want to see xsi:type="ns3:DistinguishedFolderIdType" in this line. In original SOAP it looks like:

 <FolderIds>
  <DistinguishedFolderId Id="inbox" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" /> 
  </FolderIds>

So. How to solve this problem?

回答1:

IStar,

First off, I'm not familiar with gSOAP nor am I familiar with this syntax. In fact, I don't expect to answer your question but I'll give it a shot. With that said, gSOAP is trying to create XML that is not supported by EWS. I think the following lines are incorrect, and there probably needs to be another line or two:

gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->union_NonEmptyArrayOfBaseFolderIdsType.DistinguishedFolderId = dfit;
gftRoot->FolderIds = (ns3__NonEmptyArrayOfBaseFolderIdsType*)dfit;

I think that second line is instructing gSOAP to make the FolderIds element to be something it shouldn't be. It looks like there is some sort of conflation of the FolderIds and DistinguishedFolderId element structure.

Perhaps it should look something like:

ns3__NonEmptyArrayOfBaseFolderIdsType *fids = new ns3__NonEmptyArrayOfBaseFolderIdsType();
fids->DistinguishedFolderId = dfit
fids->__size_NonEmptyArrayOfBaseFolderIdsType = 1;
gftRoot->FolderIds = fids;


回答2:

Well, i figured out how to make it works:

//get folder
    ns1__GetFolderType *gftRoot = new ns1__GetFolderType(); 
    gftRoot->FolderIds = new ns3__NonEmptyArrayOfBaseFolderIdsType();
    gftRoot->FolderIds->__size_NonEmptyArrayOfBaseFolderIdsType = 1; //there we specify how many folders elements in FolderIds array
    gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType = new __ns3__union_NonEmptyArrayOfBaseFolderIdsType(); //create one element of array
    gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->__union_NonEmptyArrayOfBaseFolderIdsType = 2; //this indicates, which class/structure are taken from union
    gftRoot->FolderIds->__union_NonEmptyArrayOfBaseFolderIdsType->union_NonEmptyArrayOfBaseFolderIdsType.DistinguishedFolderId = dfit; //push dfit to element
    gftRoot->FolderShape = frst;

    __ns1__GetFolderResponse response;

    int ret = proxy->GetFolder(gftRoot, response);