HOW TO: Use REST to POST in Hosted SharePoint Apps
This blog post is a contribution from Mustaq Patel, an engineer with the SharePoint Developer Support team.
This blog post demonstrates the use of SharePoint 2013 REST from AppWeb to issue HTTP POST on HostWeb. This does not require cross domain calls or the use of SP.RequestExecutor.js. Cross-site collection calls are demonstrated in Solving cross-domain problems in apps for SharePoint.
So let’s dive into the App. This App is an OnPrem SharePoint hosted app which will create a sub-site in the hostweb, create a custom List within that sub-site and create list item in the custom list.
This can be further enhanced to do the full CRUD operations using REST as demonstrated in https://msdn.microsoft.com/en-us/library/jj164022.aspx
Prerequisite
You will need a SharePoint 2013 environment that is configured to develop and deploy SharePoint Apps. If not please follow below MSDN to configure your environment for SharePoint Apps :How to: Set up an on-premises development environment for apps for SharePoint
Steps
1. Create a SharePoint Hosted App using Visual Studio 2012 using your on premise Site Url to deploy the App.
2. Edit default.aspx markup and add the following to PlaceHolderMain
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<div>
<p id="message"></p>
</div>
<br /><br />
<input id="btncreatespweb" type="button" value="Create SPWeb on HostWeb" onclick="createSPWeb();" />
<input id="btncreatesplist" type="button" value="Create SPList on HostWeb" onclick="createSPList();" />
<input id="btncreatesplistitem" type="button" value="Create SPListItem" onclick="createSPListItem();" />
</asp:Content>
3. Edit App.js and replace all the code with the following :
'use strict';
var hostweburl;
var appweburl;
// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
hostweburl= decodeURIComponent(getQueryStringParameter("SPHostUrl"));
appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
});
function createSPWeb() {
$.ajax(
{
url: appweburl +
"/_api/SP.AppContextSite(@target)/web/webinfos/add?@target='" +
hostweburl + "'",
type: "POST",
data: JSON.stringify(
{
'parameters':
{
'__metadata': { 'type': 'SP.WebInfoCreationInformation' },
'Url': 'RestSubWeb',
'Title': 'RestSubWeb',
'Description': 'REST created web',
'Language': 1033,
'WebTemplate': 'sts',
'UseUniquePermissions': false
}
}
),
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: successHandler,
error: errorHandler
});
}
function createSPList() {
$.ajax(
{
url: appweburl +
"/_api/SP.AppContextSite(@target)/web/lists?@target='" +
hostweburl + "/RestSubWeb'",
type: "POST",
data: JSON.stringify({
'__metadata': { 'type': 'SP.List' },
'AllowContentTypes': true,
'BaseTemplate': 100,
'ContentTypesEnabled': true,
'Description': 'My TestCustomList description',
'Title': 'TestCustomList'
}),
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: successHandler,
error: errorHandler
});
}
function createSPListItem() {
$.ajax(
{
url: appweburl +
"/_api/SP.AppContextSite(@target)/web/lists/GetByTitle('TestCustomList')/items?@target='" +
hostweburl + "/RestSubWeb'",
type: "POST",
data: JSON.stringify({
'__metadata': { 'type': 'SP.Data.TestCustomListListItem' },
'Title': 'Added from RESTSPApp'
}),
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: successHandler,
error: errorHandler
});
}
function successHandler() {
$('#message').text('Success');
}
function errorHandler(data, errorCode, errorMessage) {
$('#message').text('Error ' + errorMessage);
}
function getQueryStringParameter(paramToRetrieve) {
var params =
document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}
4. Next navigate to AppManifest –> Permissions. Select Scope=Site Collection and Permission=Full Control
5. Deploy the App. Once deployed, the default page should load
6. Click “Create SPWeb on HostWeb”. Once you see the text “Success” above the button, go to the Host web where you will see the new sub-site “RestSubWeb” created
7. Create a List and List item using “Create SPList on HostWeb” and “Create SPListIiem” buttons.
Here’s how the code works without using cross-domain JavaScript library. The AppContextSite object will create appropriate context based on @target parameter and call the appropriate REST endpoint to do POST to SharePoint. REST url syntax used here is appWebUrl/_api/SP.AppContextSite(@target)/web?@target='https://devsite'
Where appWebUrl/_api/SP.AppContextSite(@target)/ does not change but the parameters web? is the based the object that you’re accessing and @target value is the url of the site from where you are trying to access it.
For example to access list on the host web use appWebUrl/_api/SP.AppContextSite(@target)/web/lists?@target='” +hostWebUrl+ “’”
To create custom field for a list in host web
appWebUrl/_api/SP.AppContextSite(@target)/web/lists(guid ‘list GUID’)/Fields?@target='” +hostWebUrl+ “’”
I hope this simple demo helps writing robust Apps for SharePoint using REST API.
Comments
Anonymous
July 15, 2013
How would you POST multiple SP Items at once to a list?Anonymous
July 22, 2013
Hi Mustaq Patel, Thanks for the Post, How to create Custom Content Types with Custom Fields and How to associate the Content Type with the List while creating using REST. ThanksAnonymous
December 10, 2013
Great sample! I'm trying to translate this to a REST call to Excel Services. I get a not found error (I guess on the endpoint?). Is this supported? var url = appweburl + "/_api/SP.AppContextSite(@target)/_vti_bin/ExcelRest.aspx/Shared%20Documents/users.xlsx/model/ranges('users')?@target='" + hostweburl + "'"; alert url; $.ajax({ type: "POST", headers: { "accept": "application/json;odata=verbose", "content-type": "application/json;odata=verbose", "X-RequestDigest": $("#__REQUESTDIGEST").val() }, url: url, contentType: "text/html; charset=utf-8", dataType: "html", success: function (data, status) { var userData = data; alert "OK"; }, error: function (xmlRequest) { var error = xmlRequest; alert 'error: ' + xmlRequest.status + ' nr ' + xmlRequest.statusText + 'nr' + xmlRequest.responseText); } });Anonymous
May 16, 2014
Great post! The code worked right away.Anonymous
June 26, 2014
Hey, I am trying to make a REST call using your code within a SharePoint-hosted App on my E3. I have a simple form with a button which has an onclick="save()" where save() function should make a REST call. The function fails and the REST call is never made.
What javascript includes do I need to include? In my App.js, in the document.ready function, I made a call through CSOM to get the user name and that seems to work.
This seems very simple and I am not sure what I am missing. Very frustrating.Anonymous
June 29, 2014
I am trying to call the CreateListItem from SP Modal Dialog and it does not succeed. Does anyone know why this could be? Do I need to use the cross-domain Library in this case? Or possibly the JS files are not loaded properly?Anonymous
September 17, 2014
Hey I am trying to add fields to my custom List using REST Call
Can we add them in the List creation ?
Or I need to create the list first then create the columns one by one ?Anonymous
September 25, 2014
when i implement the same thing in client web part, not getting the value $("#__REQUESTDIGEST").val(). Due to this error functionality is not working.Anonymous
May 07, 2015
createSPListItem is not throwing any error, nor it is creating any item in parent list.Anonymous
May 20, 2015
the above code is not working getting error Error Forbidden on clicking button " create SPweb on hostweb"