Issue in making cross-domain call to Project server oData feed from SharePoint Add-In (app) - cross-domain

I am developing a SharePoint Hosted Add-In which will display project server projects. I am using SP.RequestExecutor to make cross domain calls. It gives me the following error “Cannot find resource for the request ProjectData.”
I have given the Reporting (Project Server) Read permission in AppManifest file. Following is my code.
$(document).ready(function () {
SP.SOD.executeFunc('SP.js', 'SP.ClientContext', initializePage);
});
function initializePage() {
hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
var scriptbase = hostweburl + "/_layouts/15/";
$.getScript(scriptbase + "SP.RequestExecutor.js", getProjectList);
}
function getProjectList() {
var executor;
executor = new SP.RequestExecutor(appweburl);
executor.executeAsync({
url: appweburl + "/_api/SP.AppContextSite(#target)/ProjectData/Projects?$filter=ProjectState eq 'In Progress'&$select=ProjectId,ProjectName&#target='" +
hostweburl + "'",
method: "GET",
crossDomain: true,
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var jsonObject = JSON.parse(data.body);
alert(jsonObject.d.results);
},
error: function (error) {
alert(error.body);
}
}
);
}

There is no need to use SP.AppContextSite(#target).
Try below URL -
url: appweburl + "/_api/ProjectData/Projects?$filter=ProjectState eq
'In Progress'&$select=ProjectId,ProjectName"
The permissions for your app should include Read permissions for Reporting.

Related

Access denied, SharePoint app. Copy file to another site collection

UPDATE: I understand now that by installing an app in web scope, it only gets access to the hostweb and appweb. So I tried to batchinstall the app - and now the APP works.
However, the App Part isnt available other than in the App Catalog.
Does Anyone know a way to give the App Part permissions to other site collections, or batch install the App Part so its available in other places than app catalog?
have this code that I'm using for downloading a file from one sitecollection, and trying to upload it to another, in sharepoint online.
I'm getting a 403 that im not allowed to upload the file. The DOWNLOAD is fine.
Does anyone have any clues?
var web;
var hostweburl;
var appweburl;
$(document).ready(function () {
sharePointReady();
});
function sharePointReady() {
hostweburl =
decodeURIComponent(
getQueryStringParameter('SPHostUrl')
);
appweburl =
decodeURIComponent(
getQueryStringParameter('SPAppWebUrl')
);
var scriptbase = hostweburl + '/_layouts/15/';
$.getScript(scriptbase + 'SP.Runtime.js',
function () {
$.getScript(scriptbase + 'SP.js',
function () { $.getScript(scriptbase + 'SP.RequestExecutor.js', copyAndUploadFile); }
);
}
);
}
function getQueryStringParameter(param) {
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] == param) {
return singleParam[1];
}
}
}
function copyAndUploadFile() {
var targetUrl = "https://sogetiumea-my.sharepoint.com/personal/simonagren_sogetiumea_onmicrosoft_com";
var executor = new SP.RequestExecutor(appweburl);
var fileContentUrl = "_api/SP.AppContextSite(#target)/web/GetFileByServerRelativeUrl('/_catalogs/theme/15/fontscheme003.spfont')/$value?#target='" + hostweburl + "'";
var fileTargetUrl = "_api/SP.AppContextSite(#target)/web/GetFolderByServerRelativeUrl('_catalogs/theme/15')/Files/Add(url='fontscheme003.spfont', overwrite=true)?#target='" + targetUrl + "'";
$.ajax({
url: "_api/contextinfo",
type: "POST",
contentType: "application/x-www-url-encoded",
dataType: "json",
headers: {
"Accept": "application/json; odata=verbose",
},
success: function (data) {
var digest = data.d.GetContextWebInformation.FormDigestValue;
var getFileAction = {
url: fileContentUrl,
method: "GET",
binaryStringResponseBody: true,
success: function (getFileData) {
var results = data.body;
var copyFileAction = {
url: fileTargetUrl,
method: "POST",
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": digest
},
contentType: "application/json;odata=vebose",
binaryStrinRequestBody: true,
body: getFileData.body,
success: function (copyFileData) {
alert("kopiering gick bra");
},
error: function (ex) {
alert(JSON.stringify(ex));
}
};
executor.executeAsync(copyFileAction);
},
error: function (ex) {
alert(JSON.stringify(ex));
}
};
executor.executeAsync(getFileAction);
},
error: function (ex) {
alert(JSON.stringify(ex));
}
});
}
I used a workaround of sort.
I added the app part to the app catalog, and used a hardcoded value to the mysite site collection (used as source for downloading/copying the file).
Using developer tools I copied the html for the iframe used to show the app part i n the app catalog.
I activated publishing on mysites root site collection.
I added a scripteditor webpart. Then I added the copied iframe code. Voila, now the "app part" works.
At first the app listens to the current user, checks if a personal site exists, else it creates it.
Copies as cusom spcolor file from the mysite "_catalogs/theme/15" to same folder on the current users personal site.
Applies the spcolor file in "Applytheme".
This is based on the idea that Vesa has done with a provider hosted app!

cross domain issue when accessing sharepoint list from sharepoint app

This is my code
function getListItem(url, listname, id, complete, failure) {
// Getting our list items
$.ajax({
url: url + "/_api/lists/getbytitle('"+ listname +"')/items",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
// Returning the results
complete(data);
},
error: function (data) {
failure(data);
}
});
};
The url is coming correctly, also on checkng the full url parameter in ajax call, it is returning data when i open that in new tab
But since this ajax call is made inside a sharepoint app that is in a different domain, its throwing an error - No 'Access-Control-Allow-Origin' header is present on the requested resource
What change should i make in my site to make that list available for cross domain call.
Info:
the site url is http://www.vignesh.cloudappsportal.com/
The app url is xxxx.apps.cloudappsportal.net/CloudAppsTrial/Pages/Default.aspx
Cross domain calls are blocked by modern web browsers due to security concerns. This is a common issue in web based development and is particularly relevant due to the nature of SharePoint hosted Apps. For example, when accessing data in the parent web (http://consoto.sharepoint.com) from an App (hosted at http://apps.sharePoint.com/SPApp) the calls will be blocked. To get round this you can use the SP.RequestExecutor.js script to relay messages to SharePoint from within the same domain.
Example
function getListItems(hostUrl,appWebUrl, listTitle,success,error)
{
var url = appWebUrl + "/_api/SP.AppContextSite(#target)/web/lists/getbytitle('" + listTitle + "')/items?#target='" + hostUrl + "'";
var executor = new SP.RequestExecutor(appWebUrl);
executor.executeAsync(
{
url: url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var data = JSON.parse(data.body);
success(data.d.results);
},
error: error
});
}
Usage
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
var appWebUrl = getParameterByName('SPAppWebUrl');
var hostUrl = getParameterByName('SPHostUrl');
var scriptbase = hostUrl + '/_layouts/15/';
$.getScript(scriptbase + "SP.RequestExecutor.js", function (data) {
getListItems(hostUrl,appWebUrl, 'Tasks',function(data){
//print list items properties
data.forEach(function(item){
console.log(item.Title);
});
},
function(error){
//error handling goes here...
});
});
About App permissions
An app for SharePoint uses permission requests to specify the permissions that it needs to function correctly. The permission requests specify both the rights that an app needs and the scope at which it needs the rights. These permissions are requested as part of the app manifest. The following picture demonstrates how to grant read access for an App
Follow App permissions in SharePoint 2013 for a more details.

Asana POST Task

I am trying to post a task in asana with the following node/express function
exports.addTask = function(req, res) {
var url ='/api/1.0/tasks?workspace=' + req.session.workspace_id
var postBase = "app.asana.com";
var options = {
host: postBase,
port: 443,
path: url,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + JSON.parse(req.session.user).access_token,
}
};
var req2 = https.request(options, function(res2) {
res2.on('data', function(chunk) {
console.log(chunk + "");
});
res2.on('error', function(e){
console.log(e.message);
});
});
req2.end();
}
I get the correct response back from asana which is:
{"data":{"id":8253508011735,"created_at":"2013-10-20T16:17:53.140Z","modified_at":"2013-10-20T16:17:53.140Z","name":"","notes":"","completed":false,"assignee_status":"upcoming","completed_at":null,"due_on":null,"workspace":{"id":1361701377437,"name":"getspur.com"},"assignee":null,"parent":null,"followers":[{"id":1050147548705,"name":"Gorkem Yurtseven"}],"projects":[],"tags":[]}}
but nothing seems to be added in my asana tasks..
ps. I am currently at the Facebook Hackathon in New York,so bring it on!
It could be because the assignee is null, and it's not in any projects - that basically makes it impossible to find (except perhaps via Search?)
Without seeing the post body I'm not sure if that's intentional or just a formatting issue.

SharePoint 2010 REST API JQUery Insert, Update, Delete

Can anyone explain or point me to a link with samples of doing Update, Delete using Jquery with the SharePoint 2010 Rest API?
I have the insert working and of course queries since the MSDN documentation explains and every tutorial on the net explains queries but just wondering if anyone ever inserts, updates, deletes data instead of only samples and tutorials on querying? Yes I know I can use the CSOM but I want to learn how this is done via jquery and sharepoint rest?
Also I want to use Merge for updating.
Here's the working insert code:
function insertMilestone() {
var mileStonesListUrl = "/_vti_bin/listdata.svc/Milestones";
var milestone = {};
milestone.Title = "Testing from REST";
var entry = JSON.stringify(milestone);
$.ajax({
type: "POST",
url: mileStonesListUrl,
data: entry,
contentType: "application/json; charset=utf-8",
error: function (xhr) {
alert(xhr.status + ": " + xhr.statusText);
},
success: function () {
getAll();
}
});
}
How to perform CRUD operations using SharePoint 2010 REST Interface
Create
In order to perform a Create operation via REST, you must perform the following actions:
Create an HTTP request using the POST verb.
Use the service URL of the list to which you want to add an entity as
the target for the POST.
Set the content type to application/json.
Serialize the JSON objects that represent your new list items as a
string, and add this value to the request body
JavaScript example:
function createListItem(webUrl,listName, itemProperties, success, failure) {
$.ajax({
url: webUrl + "/_vti_bin/listdata.svc/" + listName,
type: "POST",
processData: false,
contentType: "application/json;odata=verbose",
data: JSON.stringify(itemProperties),
headers: {
"Accept": "application/json;odata=verbose"
},
success: function (data) {
success(data.d);
},
error: function (data) {
failure(data.responseJSON.error);
}
});
}
Usage
var taskProperties = {
'TaskName': 'Order Approval',
'AssignedToId': 12
};
createListItem('https://contoso.sharepoint.com/project/','Tasks',taskProperties,function(task){
console.log('Task' + task.TaskName + ' has been created');
},
function(error){
console.log(JSON.stringify(error));
}
);
Read
In order to perform a Read operation via REST, you must perform the following actions:
Create an HTTP request using the GET verb.
Use the service URL of the list item to which you want to add an
entity as the target for the GET.
Set the content type to application/json.
JavaScript example:
function getListItemById(webUrl,listName, itemId, success, failure) {
var url = webUrl + "/_vti_bin/listdata.svc/" + listName + "(" + itemId + ")";
$.ajax({
url: url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
success(data.d);
},
error: function (data) {
failure(data.responseJSON.error);
}
});
}
Usage
getListItemById('https://contoso.sharepoint.com/project/','Tasks',2,function(taskItem){
console.log(taskItem.TaskName);
},
function(error){
console.log(JSON.stringify(error));
}
);
Update
To update an existing entity, you must perform the following actions:
Create an HTTP request using the POST verb.
Add an X-HTTP-Method header with a value of MERGE.
Use the service URL of the list item you want to update as the target
for the POST
Add an If-Match header with a value of the entity’s original ETag.
JavaScript example:
function updateListItem(webUrl,listName,itemId,itemProperties,success, failure)
{
getListItemById(webUrl,listName,itemId,function(item){
$.ajax({
type: 'POST',
url: item.__metadata.uri,
contentType: 'application/json',
processData: false,
headers: {
"Accept": "application/json;odata=verbose",
"X-HTTP-Method": "MERGE",
"If-Match": item.__metadata.etag
},
data: Sys.Serialization.JavaScriptSerializer.serialize(itemProperties),
success: function (data) {
success(data);
},
error: function (data) {
failure(data);
}
});
},
function(error){
failure(error);
});
}
Usage
var taskProperties = {
'TaskName': 'Approval',
'AssignedToId': 12
};
updateListItem('https://contoso.sharepoint.com/project/','Tasks',2,taskProperties,function(item){
console.log('Task has been updated');
},
function(error){
console.log(JSON.stringify(error));
}
);
Delete
To delete an entity, you must perform the following actions:
Create an HTTP request using the POST verb.
Add an X-HTTP-Method header with a value of DELETE.
Use the service URL of the list item you want to update as the target
for the POST
Add an If-Match header with a value of the entity’s original ETag.
JavaScript example:
function deleteListItem(webUrl, listName, itemId, success, failure) {
getListItemById(webUrl,listName,itemId,function(item){
$.ajax({
url: item.__metadata.uri,
type: "POST",
headers: {
"Accept": "application/json;odata=verbose",
"X-Http-Method": "DELETE",
"If-Match": item.__metadata.etag
},
success: function (data) {
success();
},
error: function (data) {
failure(data.responseJSON.error);
}
});
},
function (error) {
failure(error);
});
}
Usage
deleteListItem('https://contoso.sharepoint.com/project/','Tasks',3,function(){
console.log('Task has been deleted');
},
function(error){
console.log(JSON.stringify(error));
}
);
Please follow List Items manipulation via REST API in SharePoint 2010 article for a more details.
Here is the update and delete, it wasn't as hard as I thought it was going to be and it works.
Hopefully this will help someone out because there is so much bogus information on using the REST API and I see a zillion posts on querying but none on Insert, Update, Delete.
//update
function updateMilestone(id) {
var mileStonesUrl = "/_vti_bin/listdata.svc/Milestones";
mileStonesUrl = mileStonesUrl + "(" + id+ ")";
var beforeSendFunction;
var milestoneModifications = {};
milestoneModifications.Title = "Updated from REST";
var updatedMilestoneData = JSON.stringify(milestoneModifications);
//update exsiting milestone
beforeSendFunction = function (xhr) {
xhr.setRequestHeader("If-Match", "*");
// Using MERGE so that the entire entity doesn't need to be sent over the wire.
xhr.setRequestHeader("X-HTTP-Method", 'MERGE');
}
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
processData: false,
beforeSend: beforeSendFunction,
url: mileStonesUrl,
data: updatedMilestoneData,
dataType: "json",
error: function (xhr) {
alert(xhr.status + ": " + xhr.statusText);
},
success: function () {
alert("Updated");
getAll();
}
});
function deleteMilestone(id) {
var mileStonesUrl = "/_vti_bin/listdata.svc/Milestones";
mileStonesUrl = mileStonesUrl + "(" + id+ ")";
$.ajax({
type: "DELETE",
contentType: "application/json; charset=utf-8",
processData: false,
url: mileStonesUrl,
error: function (xhr) {
alert(xhr.status + ": " + xhr.statusText);
},
success: function () {
alert("deleted");
getAll();
}
});
}
}
I recently worked with the REST API for SP 2013, as a Example POC that can be used for any call implementation i.e. JQuery, C# etc.
Using POSTMAN
First get your digest token:
A method was found on this site : http://tech.bool.se/basic-rest-request-sharepoint-using-postman/​
[Credit where credit is due]
POST
http://<SharePoint Domain Url>/sites/<Site name>/_api/contextinfo
Header:
Accept : application/json;odata=verbose
Body:
Clear the body ​
From the payload use "FormDigestValue" value and put it into your headers with the key : X-RequestDigest when making actions that alter items in SharePoint.
Reading data:
GET
http://<SharePoint Domain Url>/sites/<Site name>/_api/web/getfolderbyserverrelativeurl('/Sites/<Site Name>/Shared Documents/My Folder')/files?$select=Name
Headers:
Accept : application/json;odata=verbose​
When it comes to create, update , delete you need the digest token or an authorization token to perform these actions, this token is highlighted at the begining to to retrieve.
​Creating Data
POST
http://<SharePoint Domain Url>/sites/<Site Name>/_api/web/folders​
Headers:
Accept : application/json;odata=verbose
X-RequestDigest : 'GUID looking toking'
Content-Type : application/json;odata=verbose
Body:
{ '__metadata': { 'type': 'SP.Folder' }, 'ServerRelativeUrl': '/Sites/<Site Name>/Shared Documents/Some Folder/POC3'}​
Note:
'ServerRelativeUrl' the folder on the end POC3 is the folder that I want to create
Related resources:
http://msdn.microsoft.com/en-us/library/office/fp142380(v=office.15).aspx
Note: PostMan was used for this example and other application may need you to url encode the endpoint.
The above Request Structure can be used for all requests, the related resource highlights some of the standard methods that can be used with the REST Api

Ajax request not working in IIS

This code runs in Visual Studio but not in IIS.
$('#addMessage').click(function () {
var textMessage = $('#ticketMessage').val();
var isInternal = $('#isInternal')[0].checked;
var ticketID = $('#TicketID').val();
$.ajax({
url: '/Ticket/AddMessage',
type: 'POST',
data: { textMessage: textMessage, isInternal: isInternal, ticketID: ticketID },
success: function (data) {
var tbody = $('#allMessages').children()[0];
tbody.innerHTML = tbody.innerHTML + data;
$('#ticketMessage').val("");
$('#isInternal')[0].checked = false;
}
});
});
What to fix in this code for the ajax request to run properly in IIS?
Please check with URL, Because sometimes the URL may point to 404 error page.
Because, the file is hosted in virtual folder. So, Please try with fully URL first, to check if it work fine. Better use Firebug or IE 9 developer tools. we can trace the Ajax requests.
I mean like this
$.ajax({
url: 'http://localhost/yourapplication/Ticket/AddMessage',
type: 'POST',
data: { textMessage: textMessage, isInternal: isInternal, ticketID: ticketID },
success: function (data) {
var tbody = $('#allMessages').children()[0];
tbody.innerHTML = tbody.innerHTML + data;
$('#ticketMessage').val("");
$('#isInternal')[0].checked = false;
}
});

Resources