Menu

SharePoint client object model and windows store apps

Today’s post will be about interesting topic, related to SharePoint client object model and windows store apps. As you aware SharePoint 2010 gave developers a good option to interact with SP by utilizing JavaScript API. In 2013 version that API was really extended and SharePoint is going to keep that way. Everything is moving to HTML5, so such a solid platform has to be ready, especially if you want to write your apps without any server side change to the server. You just need to keep in mind that JCOM has bunch of limitations, so for general tasks it could be enough, but for some real heavy changes you will need to touch server.

JCOM would be perfect, if you are going to populate your apps with content from SharePoint. Also, JCOM is perfect if you want to perform update/delete/create operations.

What we are going to do is a simple task against SharePoint – we will create an app to load different content types from SharePoint (Calendar Events).

So why this post is a different to something which you have already potentially seen in the Web?

The first example actually using client side model inside WinRT, however I couldn’t be able to run that example with windows 8.1. Needs some changes I guess.

The second example is REST example. As you know it is also possible to use REST api to access the portal. You could be aware of a good js library data.js, which will help you easily get/update simple data.

We are going to use pure JavaScript with JCOM provided by SharePoint. In most cases you can use this option when you have your app published to SharePoint and you have no problems accessing client context. However if you publish you web page to the separate server and will try to access sharepoint objects using client context – the code won’t work. So, there are couple tricky things you need to add to your app to be able to work with JCOM. Let’s start.

1.Creating simple Navigation Windows Store App project.

I am not going to emplane how to do it. Just get the source code which I have prepared here: ShrepointJSCOM

So when you run the app you should see something similar to this:

The app has just one list, called Calendar and currently the data comes from array. Will need to replace it after with real data from SP.

errorCallback("Error when requesting the Form Digest. HTTP return code "+http.status);

}

}

}

http.send(payload);

&lt;pre&gt;

If you used right credentials, SP should return a response which will contain different headers: Version of SP etc and also digest. Digest is something like a key, when you authenticate first time to SP, the page you are on will have hidden digest input control. After, when you are navigating from page to page this value will be passed between pages and sp won’t ask you to login again and again. So, with on premises environment, you are authenticating against your on-prem SharePoint STS and as soon as you get in, you will get that digest key which will open SP doors for you.

With SP online, when you perform authentication, you are doing it against Microsoft STS. Microsoft STS issues you a token, you submit that token to your SP site and receive digest key. So, in both cases to be able to use client object model, SP should find that digest input control with value from where you are executing your code.

So, when your application is published to sp as web part, let’s say, and you have a javascript code in your web part to access SP objects, the page from where you call client model api has that digest. You can view source code of the page and look for element with id=’__REQUESTDIGEST’.

That’s why when you have an web app published to the different server you don’t have that request digest element with appropriate value, so you are just not able to get the right client context. However you can cheat the SP client object model))

In this app have a look at file serviceAuthentication.js. We will handle these two cases when authentication to SP online and Sp on prem.

3. Cheating the SP client object model

I have decided that it could be kind of painful for me to explain all steps. You just can grab working application in attachments. We just will walk through all difficult (in my opinion) places. Forgot to mention, that some files from app could be very helpful for devs who want to build offline apps. I have found these files from different MS showcases and just want to make a clean demo from where to start.

Ok, we know that this digest value is so imported, so perhaps somewhere in jcom there are some functions which looking for that tag on the page and for its value.

I have found from Microsoft resources that jcom will use default function getElementsByName and will pass parameter: __REQUESTDIGEST. So what we need to do is to overwrite

default method getElementsByName and as soon as we get parameter equal to __REQUESTDIGEST we need to return our own field, naking jcom thinks that we are on the normal SP page which by default contains that input field.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

&lt;/pre&gt;&lt;/pre&gt;

varformdigest={

value:"",

tagName:"INPUT",// Note that this has to be capitalized. Otherwise, SP complains that the digest is missing

type:"hidden"

};

vardocument={

documentElement:{},

cookie:"",

URL:"",

getElementsByName:function(name){

if(name=='__REQUESTDIGEST'){

return[formdigest]

}

},

getElementsByTagName:function(name){

return[]

}

};

&lt;pre&gt;

In this case client object model will look for digest input field, and using our overrided method will get our own input field. Done.

Another thing, as we are going to overwrite the default document function it is better to put that logic inside Web Worker. I think here is a good example

of where Web Workers can be used. We will have kind our own document instance where we can modify default methods and have digest field only inside that worker. IF you are not familiar with Web Workers have a look and html5 documentation. What also we can do with web workers, we can create many instances of doc and let’s say use one web worker to work with SP 2013 and have another one working with SP2010 at the same time in the same application.

HTML5 practice guides suggest to use web workers for data pushing/pooling. So, this is what I have done in the app also.

There are plenty of code in the app, so I just will show the diagram of command flow:

1. So first we call method from Data.js to load calendar events. Data.js has a registered web worker for DataRouter.js. So, we just post message saying: “Hey, load calendar events”.

2. DataRouter.js has imported file serviceAuthentication.js. This file actually is doing all authentication against different version of SP. So, after receiving message from data.js, DataRouter will register two different web workers for different version of SP – spDataProvider.js. This worker is what I have explained before with “RequestDigest” field. At that moment we just have two web workers which imitates SharePoint page, but we don’t know which version of SP we are going to connect until we authenticate.

3. Authenticate to SP

4. Return Digest and Version

5. Having version of SP and digest, dataRouter will pick right web worker (spDataProvider) and will post to it version and digest.

6. spDataProvider now has digest and can execute queries against SP. Query calendar events and post message back with data and successful status.

7. DataRouter gets successful message from spDataProvider and just redirect it to the parent – data.js

ps. Here is a just a simple example how to get calendar events, but you can also do many-many things like uploading files, creating sites and subsites, adding users to security groups and so on. Have a look at javascript api for sp. Also let me know if you will have problems to implement it, I have good examples as well.