How to get error details from UpdateListItems SOAP response? - sharepoint

I'm writting an iOS-client for Microsoft SharePoint. My goal is to update a datetime field of a list item and get details on errors. I have a datetime field with custom server-side validation.
Here is a request to /_vti_bin/Lists.asmx:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<UpdateListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>{405FFE91-946E-4B2F-861E-DDB24F1629F2}</listName>
<updates>
<Batch OnError="Continue" ListVersion="1">
<Method ID="1" Cmd="Update">
<Field Name="ID">1</Field>
<Field Name="DateTime_x0020_E">2000-08-08 07:00:00 +0000</Field>
</Method>
</Batch>
</updates>
</UpdateListItems>
</soap:Body>
</soap:Envelope>
Here is a response:
?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<UpdateListItemsResponse
xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<UpdateListItemsResult>
<Results>
<Result ID="1,Update">
<ErrorCode>0x8102001c</ErrorCode>
<ErrorText>Invalid date/time value.
A date/time field contains invalid data. Please check the value and try again.</ErrorText>
<z:row ows_ContentTypeId="0x0100D3AA6E2413CF1645A9101D3421B797AE" ows_Title="test of time" ows_DateTi... skipped...
This response doesn't say anything about valid range of this field. However, when I try to set invalid date at SharePoint site, I get proper error:
Q: how to get details on error using SharePoint SOAP service?

I've found out where is my mistake. The field is date-only, so probably SharePoint doesn't accept value as 2000-08-08 07:00:00 +0000. When I send date only:
<Field Name="DateTime_x0020_E">1995-08-08</Field>
I get the proper error text:
<Result ID="1,Update">
<ErrorCode>0x810200c5</ErrorCode>
<ErrorText>[DateTime E] - [Date should be after July 1, 2007]</ErrorText>
...
</Result>

Related

How to update SharePoint List Item with no ID column

I am trying to update a status filed in a SharePoint list. Did some googling, found most of the examples are using an ID column to locate the list item, but my list doesn't have such column, only a windows login and a status columns. I am wondering what the XML would be like?
This is what I come up with, but it doesn't work:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<UpdateListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>SPUsers</listName>
<updates>
<Batch PreCalc='TRUE' OnError='Continue'>
<Method ID="1" Cmd="Update">
<Field Name="ID">ABC</Field>
<Field Name="ItemStatus">Completed?ID=ABC</Field>
</Method>
</Batch>
</updates>
</UpdateListItems>
</soapenv:Body>
</soapenv:Envelope>
This is the result:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<UpdateListItemsResponse xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<UpdateListItemsResult>
<Results>
<Result ID="1,Update">
<ErrorCode>0x80004005</ErrorCode>
<ErrorText>Cannot complete this action. Please try again.</ErrorText>
</Result>
</Results>
</UpdateListItemsResult>
</UpdateListItemsResponse>
</soap:Body>
</soap:Envelope>
Any idea what went wrong?
Thank you.
SharePoint will generate list item ID automatically, the default view just not show the ID field, you could go to list view settings to show the field so you could know the ID.
I believe all list items in SharePoint get an auto generated ID. I'd use the list view or pull the list items to see if an id exists.

Node Soap: How to override request payload for SOAP method

I've been shifting between node-soap and strong-soap since they both generate different payloads and work similarly (All I have to do is change the require path and I can shift between strong-soap and node-soap without changing existing code)
However, when I'm using node-soap, I't really does generate these weird payloads.
Here's an exmaple
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:i0="http://services.redacted.com/Contracts" xmlns:msb="http://schemas.microsoft.com/ws/06/2004/mspolicy/netbinary1" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:tns="http://services.redacted.com/Contracts" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<stns:SecurityToken xmlns:stns="http://services.redacted.com/Security">
<ServiceKey>123</ServiceKey>
<UserId>123</UserId>
<Username>123</Username>
<Password>123</Password>
</stns:SecurityToken>
</soap:Header>
<soap:Body>
<DataService_GetProfiles_InputMessage />
</soap:Body>
</soap:Envelope>
So it's all fine, except the method I'm trying to invoke is called: GetProfiles not DataService_GetProfiles_InputMessage and subsequently the service I'm trying to communicate with doesn't recognise the method I'm trying to invoke.
What does work (And what strong-soap generates)
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:i0="http://services.redacted.com/Contracts" xmlns:msb="http://schemas.microsoft.com/ws/06/2004/mspolicy/netbinary1" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:tns="http://services.redacted.com/Contracts" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<stns:SecurityToken xmlns:stns="http://services.redacted.com/Security">
<ServiceKey>123</ServiceKey>
<UserId>123</UserId>
<Username>123</Username>
<Password>123</Password>
</stns:SecurityToken>
</soap:Header>
<soap:Body>
<GetProfiles />
</soap:Body>
</soap:Envelope>
Now that makes sense. However, due to other constraints we can't stick to strong-soap.
Is there a way I can override the requested payload? Is there a reason It's generating this weird XML?
My Code:
this.dataClientConnection.DataService.BasicHttpBinding_DataService.GetProfiles()
The solution was the following:
Documentation LIST ITEM 5
You will however override the entire document you're sending.
I did not figure out a way to override certain nodes.

Constructing SOAP Security Header for wsse:UserToken

I'm trying to manually construct a SOAP request to an Address Validation webservice that requires a SOAP <Security> header to be set. But I can't seem to get it right. The technology stack I'm using (Salesforce) necessitates me forming the XML myself.
From the WSDL:
<s0:Policy s1:Id="derm.service.common.esb.wspolicy.UNT.1">
<wssp:Identity xmlns:wssp="http://www.bea.com/wls90/security/policy">
<wssp:SupportedTokens>
<wssp:SecurityToken TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wssusername-token-profile-1.0#UsernameToken">
<wssp:UsePassword Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-usernametoken-profile-1.0#PasswordText" />
</wssp:SecurityToken>
</wssp:SupportedTokens>
</wssp:Identity>
</s0:Policy>
Full WSDL: http://pastebin.com/Z5VswYNF
From the documentation linked from the WSDL (http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf) I retrieved this example:
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>REDACTED_PLAINTEXT_USERNAME</wsse:Username>
<wsse:Password>REDACTED_PLAINTEXT_PASSWORD</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
Replacing the values with the Username / Password I've been supplied and firing off the sample request from the documentation doesn't work.
Sample request with Security header:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap="information.qld.gov.au/service/Addressing/ValidationService/2/soap">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>REDACTED_PLAINTEXT_USERNAME</wsse:Username>
<wsse:Password>REDACTED_PLAINTEXT_PASSWORD</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<soap:ParseValidAddress>
<soap:addressString>867 Main Street Woolloongabba Queensland</soap:addressString>
<soap:postcodeOption>Include</soap:postcodeOption>
<soap:meshblockOption>Exclude</soap:meshblockOption>
</soap:ParseValidAddress>
</soapenv:Body>
</soapenv:Envelope>
Everything I try gets a generic error message
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>The requested operation was rejected. Please consult with your administrator.Your support ID is: REDACTED_SUPPORT_ID</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
I've also tried the following from elsewhere on stackexchange:
<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:SOAP-ENV="SOAP-ENV">
<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>oneview</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">oneview123</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
What am I doing wrong?
I am missing the wsse namespace specification in your SOAP message.
You can find it in the link from your text:
"From the documentation linked from the WSDL (http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf)"
The value is http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd

TaxonomyClientService.GetTermSets 400 bad request

What is wrong with this SOAP request? I keep on getting 400 bad request error.
<S:Body>
<GetTermSets xmlns="http://schemas.microsoft.com/sharepoint/taxonomy/soap/">
<sharedServiceIds>
<termStoreIds>
<termStoreId>27a0a321-083f-4688-8b6e-d86b7ab42de9</termStoreId>
</termStoreIds>
</sharedServiceIds>
<termSetIds>
<termSetIds><termSetId>cb1b9444-159d-48c3-b9a7-19ebd612e796</termSetId></termSetIds>
</termSetIds>
<lcid>1033</lcid>
<clientTimeStamps>
<timeStamps><timeStamp>2304823424</timeStamp></timeStamps>
</clientTimeStamps>
<clientVersions><versions><version>1</version></versions></clientVersions>
</GetTermSets>
</S:Body>
I was struggling with this for a long time as well, and had extrapolated the same request from all the examples that I could find online.
But I managed to get it working by looking up "MS-EMMWS" (my working example below)
MS-EMMWS - Protocol Examples
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetTermSets xmlns="http://schemas.microsoft.com/sharepoint/taxonomy/soap/">
<sharedServiceIds><sspIds><sspId>0d18c636-63d4-452b-b094-6de97ee5159d</sspId></sspIds>
</sharedServiceIds><termSetIds><termSetIds><termSetId>48508451-17d5-4bdb-b1c9-7f096f680352</termSetId></termSetIds></termSetIds><lcid>1033</lcid>
<clientTimeStamps><dateTimes><dateTime>1900-01-01T00:00:00</dateTime></dateTimes></clientTimeStamps>
<clientVersions><versions><version>0</version></versions></clientVersions></GetTermSets>
</soap:Body>
</soap:Envelope>

Add Attachment with UpdateListItems?

Is it possible to add an attachment to a new list item with UpdateListItems?
I've tried this SOAP, but no dice....
Can someone share with me the proper SOAP structure to get this done?
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:UpdateListItems>
<ns1:listName>Some Calendar</ns1:listName>
<ns1:updates>
<Batch OnError="Continue" ListVersion="1">
<Method ID="1" Cmd="New">
<Field Name="ID">New</Field>
<Field Name="Title">Some Title</Field>
<Field Name="EventDate">2010-11-01 07:30:00</Field>
<Field Name="Attachments">
<Value Type="Attachments">/tmp/details.xml</Value>
</Field>
</Method>
</Batch>
</ns1:updates>
</ns1:UpdateListItems>
</ns0:Body>
</SOAP-ENV:Envelope>
Thanks!
Found the answer to my question. Apparently, using getlistitems to attach a file to an item is not possible. You have to get the _ows_ID value when creating the item, then use the AddAttachment method on the ID value of your item.

Resources