I would chase why you can't create the list via the interface in the first place, these two web service calls don't seem to include the important parameter when creating from custom templates, lets analyse the querystrings:
New Project Tasks (out of the box)
http://site/_layouts/new.aspx?FeatureId={00bfea71-513d-4ca0-96c2-6a47775c0119}&ListTemplate=150
New Project Tasks Custom (saved in the list template gallery)
http://site/_layouts/new.aspx?CustomTemplate=PT6.stp&FeatureId={00bfea71-513d-4ca0-96c2-6a47775c0119}&ListTemplate=150
New Project Tasks Custom (manifest.xml edited to 151)
http://site/_layouts/new.aspx?CustomTemplate=PT6.stp&FeatureId={00bfea71-513d-4ca0-96c2-6a47775c0119}&ListTemplate=151
They all work, so my take here is that the Web Service is a no no for custom templates, or it has some secret magic (common in list definitions) since specifying only the ListTemplate without being explicitly CUSTOM won't work even in the UI.
If you can't get around with this apparent limitation, my suggestions are:
- .NET, note that this post has some voodoo in the first comment if you happen to get the same error
- Make an IFRAME with http://site/_layouts/new.aspx?CustomTemplate=PT6.stp&FeatureId={00bfea71-513d-4ca0-96c2-6a47775c0119}&ListTemplate=150 as source and fill the fields using javascript, and then trigger the OK button click, make some full page loading transition and it will even look good.
Method 2 needs to be done from the same domain, if you are not running your PHP from the same domain (unlikely) you need to create a page inside the SharePoint site to contain this hack, it can be as simple as a Web Part Page with a Content Editor Web Part in it, you read some querystring parameters, place them on the fields, trigger the OK and wait for the page to change so you can redirect to a "success" page.
Edit: I got curious and looked at the source of New.aspx, it has this little snippet (bIsCustomTemplate = strCustomTemplate != null, strCustomTemplate = querystring "CustomTemplate"):
<% if (bIsCustomTemplate) { %>
<input id="onetidCustomTemplate" type="Hidden" name="CustomTemplate" value=<%SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(strCustomTemplate),Response.Output);%> />
<% } %>
I looked at the disassembled code but I don't think we can post it here, but it only proves that the UI builds it from a post (Request.Form) and looks for the CustomTemplate parameter, and the Web Service has only those methods were you can't specify a custom template.
Sean,
I'm not sure I completely understand your calling pattern, but if you are indeed looping back to web services on the same box, you might be running into the infamous loopback issue:
https://serverfault.com/questions/32345/ie-8-authentication-denied-on-local-sharepoint-site/32485#32485
In short: executing hostname-based HTTP calls that loopback to the server from which they're issued can get blocked. If the loopback issue is in-play, you'll be able to call the web services in PROD from another box ... but not from the PROD box itself (i.e., looping back). I think this is consistent with the behavior you described above.
If Windows patch levels are different between your environments, it might explain why your code is failing in PROD but not in your other environments.
I hope this helps!
Best Answer
The string
;#
is used as a delimiter by SharePoint's lookup fields, including user fields. When working with the object model, you can useSPFieldLookupValue
andSPFieldUserValue
to convert the delimited string into a strongly-typed object. When working with the web services, however, I believe you'll need to parse the string yourself.You are correct that the first part is an integer ID: ID in the site user list, or ID of the corresponding item in the lookup list. The second part is the user name or value of the lookup column.
Nicolas correctly notes that this delimiter is also used for other composite field values, including...