7

I need to update (CRUD) SharePoint list items from a stand alone application outside of SharePoint. This application can only use JavaScript to call SP. Deploying it as an app on SharePoint won't be possible as the client doesn't have the App framework set up properly.

Can anyone help if it is possible to update SharePoint list items from a standalone webapp? and how would I go about handling authentication. Would greatly appreciate any help on this.

  • Is the stand alone app in the same domain as SharePoint? – Steve Curran Mar 5 '15 at 16:15
  • Hi Steve, they are in the same network. the webapplication is running on a webserver separate to sharepoint and has url similar to NetApplication and sharepoint site is running on Intranet. – Rammers Mar 6 '15 at 19:49
  • 1
    If both apps are in the same domain the calling app can make a call to sharepoint/_api/contextinfo and get the formdigest value. You can then use this when posting via REST to SharePoint. – Steve Curran Mar 7 '15 at 1:50
8

If the stand alone web application and SharePoint are not in the same domain, the simple answer is that you cannot unless you are using Apps.

The more complex answer is that you would need to have a proxy of some sort to do this. You could write a simple layer 7 proxy inside the non-SharePoint web app that forwards the requests and the authentication or use something like Squid or even IIS itself to do this.

Hi Robert, both applications are in the same network and wouldn't need to make calls across the firewall. Does that make easier to call SP webservices from that html/jquery page?

It's all about the same origin policy, not about networking. Since SharePoint does not support JSONP/CORS, you have to respect the same origin policy. If the systems are not in the same DNS domain (i.e. portal.company.com), then by doing an AJAX call to the SharePoint server would be enabling an XSS attack. The only way to accomplish this scenario without a proxy, would be to introduce serious security vulnerability into the your users' browsers.

Another consideration might be hosting the non-SharePoint site in the same domain as SharePoint.

In order to pass the original user's credentials you'll need to configure the WCF to use Kerberos Constrained Deligation.

  • Thanks Robert. If I were to write a custom WCF service to do this (update List items from External site), would it be possible to do the authentication on SharePoint end then? – Rammers Mar 6 '15 at 17:39
  • I updated my answer with a link to an explanation about how to also proxy the authentication. It's not really on topic here as it's not specific to SharePoint, so I didn't go into detail. – Robert Kaucher Mar 6 '15 at 17:57
  • Hi Robert, both applications are in the same network and wouldn't need to make calls across the firewall. Does that make easier to call SP webservices from that html/jquery page? – Rammers Mar 6 '15 at 19:50
  • No, it's got nothing to do with location of the systems on the network. I've updated my answer with an explanation. – Robert Kaucher Mar 6 '15 at 20:39
  • Is it possible to reverse the scenario, though? Could SharePoint host the page with the HTML and JavaScript and the other app be modified so that it can use CORS or JSONP? – Robert Kaucher Mar 6 '15 at 21:00
1

Finally managed to get this working. I created a custom REST service by following this article http://www.codeproject.com/Articles/128478/Consuming-WCF-REST-Services-Using-jQuery-AJAX-Call and deployed the service to SP box as a new IIS website and then performed CRUD operation on SP Items by using CSOM.

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

1

I am advised to provide detailed answer, sorry about it as it was my first post on SharePoint Stack Exchange. The following is my blog link where I added step by step approach how to perform CRUD operations on a List that resides on another on premises farm. Recently working on an assignment I had faced this issue and could not find any end to end solution hence I documented it at on my blog at following url:

http://zenyscorp.blogspot.ca/2017/01/end-to-end-scenario-for-using.html.

In nutshell, following are the steps required to get a list item added, updated or deleted from one farm to another: Its applicable if you have both the farms in same premises.

If Using CSOM:

  1. Get the context for the target site.
  2. Use CSOM to perform CRUD on the target.

function PerformListOperations() {

var clientContext = new SP.ClientContext( "http://sharepointtesting.xxxx.com/teams/SharePoint" );

var oList = clientContext.get_web().get_lists().getByTitle('OAuthTest');

var itemCreateInfo = new SP.ListItemCreationInformation();

this.oListItem = oList.addItem( itemCreateInfo );

oListItem.set_item('Title',$('#Title').val());

oListItem.update();

clientContext.load(oListItem);

clientContext.executeQueryAsync(onPerformListOperationsSuccess, onPerformListOperationsFail);

}

function onPerformListOperationsSuccess () {
alert("Successfully created an item using CSOM...");

}

function onPerformListOperationsFail (sender, args) {
alert('Failed to create an item using CSOM... Error:' + args.get_message());

}

$(document).ready(function () {    
$("#CreateButton").click(function () {              
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', PerformListOperations);
}); 

});

If Using REST API:

  1. Call ContextInfo REST API call and retrieve FormDigestValue value.

  2. Pass the FormDigestValue to subsequent calls to perform CRUD.

  3. Making sure that metadata type for ListItem is correct, in my case my List Name is "OAuthTestList", the SharePoint adds "ListItem" as suffix to the list name, please refer following code line:

var jsonMetaData = { __metadata: { type: 'SP.Data.OAuthTestListListItem' }, Title: newTitle };

How to get Form Digest: I am calling contextinfo REST api call as shown in following function and retrieving value FormDigestValue from GetContextWebInformation object of response. Please pay attention how I am using "Target SharePoint Farm" URLs in hostUrl and how I am using it to construct the appURL value.

function CreateAListItem(listName, newTitle) {
var formDigest;
var hostUrl = "http://sharepointtesting.xxxx.com/xxxx/SharePoint/oAuth";
var appUrl = hostUrl + "/_api/web/lists/getbytitle('" + _options.listName + "')/items";

$.support.cors = true;
$.ajax(
{
    url: hostUrl + "/_api/contextinfo",
    type: 'POST',
    xhrFields: { withCredentials: true },
    dataType: "json",       
    contentType: "application/x-www-url-encoded",
    headers: {
        "accept": "application/json;odata=verbose"
    },
    success: function (data) {
        if (data.d) {
            formDigest = data.d.GetContextWebInformation.FormDigestValue;               

            // add your logic to add an item in the list example:   
           AddListItem(formDigest, appUrl, newTitle);

        }
    },
    error: function (err) {
        alert(xhr.status + ': ' + xhr.statusText);
    }
});

}

Once the FormDigestValue is retrieved then we can save that in a variable and pass it in subsequent REST API Calls. A possible implemention of AddListItem could be as following:

function AddListItem(formDigestValue,appUrl, newTitle) { var jsonMetaData = { __metadata: { type: 'SP.Data.OAuthTestListListItem' }, Title: newTitle }; $.support.cors = true;

$.ajax({
    url: appUrl,
    type: "POST",
    contentType: "application/json;odata=verbose",
    headers: { "accept": "application/json;odata=verbose", "x-requestdigest": formDigestValue, "If-Match": "*" },
    data: JSON.stringify(jsonMetaData),    

    xhrFields: { withCredentials: true },           
    success: function (data) {
        if (data.d) {               
            //do something here;
        }
    },
    error: function (xhr) {
        alert(xhr.status + ': ' + xhr.statusText);
    }
});

}

Having said above please note that you have to add an out of box SharePoint page with a Script Editor or content query web part to perform CRUD. Doing in this way you dont need to have an app deployed to SharePoint and simply adding two webpart on a SharePoint Page along with code will do the trick.

Same code can be used from a stand alone website running under a common account, as long as you get a form digest successfully the code will work.

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review – Dikesh Gandhi Jan 24 '17 at 4:01
  • Sorry guys I have just added. It was my first post on the sharepoint.stackexchange.com :(. – Yogendra Saxena Jan 25 '17 at 21:54
  • Hi Yogendra. I am having the same requirement where I have to fetch the SharePoint Data from external application running the same account. I have posted my question here sharepoint.stackexchange.com/questions/240402/… ...Please can you have a look on it and tell me where I am going wrong – Ankit Katiyar Apr 20 '18 at 14:10
0

This was the exact problem I was facing. This is an old question but my answer might be helpful to someone else coming here.

It is possible to do this. First you have do OAuth from standalone web-app. Here are the step by step instructions in my blog -

https://medium.com/@yash_agarwal2/performing-oauth-and-rest-calls-with-sharepoint-online-without-creating-an-add-in-677e15c8d6ab#.6pf4wp83b

High Level overview -

1) Get client id and secret by registering yourself here - https://sellerdashboard.microsoft.com/Registration

2) Get Access Token, Refresh Token by following steps here -

https://msdn.microsoft.com/en-us/library/office/jj687470.aspx

Then make the rest api calls to perform CRUD operations on SharePoint data. https://msdn.microsoft.com/en-us/library/office/dn499819.aspx (Rest api reference) https://msdn.microsoft.com/en-us/library/office/jj164022.aspx (Rest api reference)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.