Wednesday, 25 March 2015

CSOM tip for making your code flexible

We all know that in CSOM, for any given object, we can specify certain properties to be brought back from the server. Something like this:

This will only bring back the Title property of the web thus reducing data traveling over the wire.

Now in this case, the second parameter of the clientContext.Load method is an object of type Expression<Func<Web, object>>[]

This is an array of Linq expressions which can be utilized to our benefit. We can convert that array into a parameter which can be passed to a "Utility" function. This function which will only get the properties specified in that array. Like this:

Then, that function can be called with different parameters depending on the properties we want to fetch from the server for that particular instance. For example:

Only get the Title and Id of the Web:

Only get the MasterUrl and the CustomMasterUrl of the web:

For both the above calls, we are not changing the GetWebDetails function. It will always return a Web object with the specified properties filled in. It will also reduce data travelling over the wire, as only the specified properties will be fetched. Thus, making your code more flexible and performance friendly.

You can also have other utility functions for Lists, Users etc. Here is a similar function for Lists:

Hope you find this useful!

Monday, 23 March 2015

Custom Taxonomy Picker for Provider Hosted Apps

When working with SharePoint Online or developing cloud friendly solutions, it can be tricky to replicate some functionality which is easily available on-premises. We had a scenario recently where the user should be able to set values for a Managed Metadata user profile property. Now if this was a farm solution, we could have used a variety of methods like User Controls, Taxonomy Pickers etc. But since this was a Provider Hosted App, all those options were not available to us.

I knew that the Office Dev Patterns and Practices project has a cloud friendly taxonomy picker but that did not fit our requirements. It requires the creation of an App web in which sense it is not a "pure" provider hosted app. Also, there were some specific requirements around styling and business logic which meant that a custom Taxonomy Picker was the only way forward.

GitHub link for this project:
https://github.com/vman/CustomTaxonomyPicker

So without much further ado, here is how the custom User Profile property taxonomy picker looks:

1) When loaded first on a page, it gets the values from the "Skills" user profile property and displays them as tags:



2) When you start typing into the input box, the auto-complete suggestions are based on the "Keywords" termset. (You can change this to get terms from another termset)



3) When you are happy with the values, click on update and your Skills user profile property will be updated with the selected values:



And that's basically how it works from an end user perspective.

Advantages:


1)  Pure provider hosted app. No App web required.  If you are on-prem and in a big enterprise, this means that you don't have to wait for a wild card DNS entry to be setup. We all know how long that can take. This can be implemented as a pure provider hosted app because all calls to SharePoint are made by using CSOM in an MVC controller.

2) Complete control. Can be customized anyway you want. If you have specific business logic which needs to manipulate data before sending it to SharePoint, then you are easily able to do so.

3) Customisable UI: The jQuery Tag-It plugin is used in this taxonomy picker. It supports jQuery ui themes and a whole lot of other styling options. More about this in the Technical details section below.

Limitations:


1) As is, this control only works with SharePoint Online/Office 365. This is because the API for writing user profile properties is not yet available for SharePoint On-Premises. But if you are up for it, you can use the UserProfileService.asmx for accomplishing the same functionality. Check out this sample to see how to do it:
https://github.com/OfficeDev/PnP/tree/master/Samples/Core.UserProfilePropertyUpdater

2) At this time, it can only be used with user profile properties. If this has to work with Taxonomy fields in a list, you will have to modify the code but the principles behind the approach would stay the same.

But hey, the source is on GitHub so you don't get to complain! Submit a pull request and I will be happy to merge it :)

Technical Details:


1) Permissions:


Since the app interacts with the Managed Metadata Service and writes to the User Profile Service, the following permissions are needed:




2) jQuery Tag-It plugin:


The completely awesome jQuery Tag-It plugin is used to present the terms as tags in the UI. It provides a wide variety of options for selecting tags. It accepts a JavaScript array of values to show auto-complete suggestions.  Check out the plugin home page for more details.

3) Get current user's skills:


When the page loads, we need to get the skills for the current user to show them by default in the control, this can be done by making a simple call to the UserProfile Service.



4) Get terms from the Keywords termset:


To show the auto-complete suggestions, the Tag-It plugin requires a JavaScript array of values. We will use a MVC controller to get the keywords from the Managed Metadata Service and pass the values as a JavaScript array to the plugin. You can use any other termset to get your values. It would also be a good idea to cache these values in the browser localStorage so you don't have to make a call to the Managed Metadata service every time the control loads.



5) Update current user's skills:

When the Update button is clicked, another call is made to the Skills MVC controller which uses the recently released user profile write methods from CSOM. More about them on Vesa Juvonen's blog:
http://blogs.msdn.com/b/vesku/archive/2014/11/07/sharepoint-user-profile-properties-now-writable-with-csom.aspx

If you are on-premises, you can still use the UserProfileService.asmx for that. See this Office Dev PnP sample:
https://github.com/OfficeDev/PnP/tree/master/Samples/Core.UserProfilePropertyUpdater

Thanks for reading! Hope you found this useful.

Wednesday, 28 January 2015

Set user profile properties using JSOM & JavaScript

User Profile properties were recently made writable from the CSOM. Vesa Juvonen has a great post about it here . In addition to that, I have also blogged about how a Tenant admin can set the user profile properties of the users in the tenant.

In this post, I will show you how to set the current user's profile properties using the JavaScript Client Object Model (JSOM). Please refer to the 2 posts I have mentioned for any additional details around this.

Right now this functionality is only available in SharePoint Online/Office 365. If you want this functionality to come to SharePoint 2013 On-Premises, please create or up-vote on the feedback here: https://officespdev.uservoice.com/

Saturday, 24 January 2015

Glimpse of the upcoming Office 365 Video API

A while ago, I wrote a post about getting all the video channels and videos from the Office 365 Video Service.  Shortly after that I got a word from Microsoft that there is going to be a public API for accessing Office 365 Videos. I was allowed to share the information as long as I mentioned that the API is not documented yet and is still being worked upon. So there is a possibility that it might change in the future so it is advised that this should not be used in production until it is fully stable and documented.

Here is how the API will work:

1) Get the right path from the discover endpoint:


https://site.sharepoint.com/sites/team/_api/VideoService.discover

The returned JSON will contain the following values among others:

{
    "IsVideoPortalEnabled": true,
    "VideoPortalUrl": "https://site.sharepoint.com/portals/hub"
}

IsVideoPortalEnabled will be true if your tenant has got Office 365 Video and VideoPortalUrl is the url which we will use to make further REST calls.

2) Get all Video channels with the VideoPortalUrl:


https://site.sharepoint.com/portals/hub/_api/VideoService/Channels

The returned JSON will contain all the channels with their unique GUIDs:

{
            "Description": "",
            "Id": "eaa748d7-97d6-43f1-8780-ce5c8acbf2bb",
            "TileHtmlColor": "#0072c6",
            "Title": "Development"
}

3) Get all videos from a single video channel:


Here, we will use the Id obtained from the previous call to get all the videos from a particular channel:

https://site.sharepoint.com/portals/hub/_api/VideoService/Channels('eaa748d7-97d6-43f1-8780-ce5c8acbf2bb')/Videos

Monday, 19 January 2015

Programmatically Follow or Unfollow a Delve Board with the REST API

In one of my previous posts, we saw how you can programmatically add a document to a Delve Board with the REST API. This is a follow up post to that in which we will see how to Follow or Unfollow a Delve board with the REST API. If you haven't already seen the previous article, I suggest you take a look at it because it explains how Delve works under the hood and how you can integrate Delve into your custom Office 365 solutions.

Please bear in mind that since Delve utilizes search internally, you will have to wait for a search crawl to take place in Office 365 before you can see results of the REST operation.

I have used JavaScript and the jQuery.ajax function to make calls to the Signals API. But you can use a variety of other options which support REST.

So without much further ado, here is the code to follow or unfollow a board in Delve:



Sunday, 18 January 2015

Get all videos from an Office 365 Video Channel with REST

Update (24/01/2015): I have just got a word from Microsoft that there is going to be a public API for accessing Office 365 Videos. The information I have got is that the API is not documented yet and is still being worked upon. So there is a possibility that it might change in the future so it is advised that this should not be used in production until it is fully stable and documented.

Here is a glimpse of the upcoming video API: http://www.vrdmn.com/2015/01/glimpse-of-upcoming-office-365-video-api.html

Original post follows:

In my previous post, we saw how you can get a list of all the video channels in your Office 365 portal with the REST API. In this post, we will see how to get a list of all the videos in a particular Office 365 Video Channel with the SharePoint REST API.

Each video channel is underpinned by a separate site collection in SharePoint Online. When you upload a video to a channel, it gets uploaded in the "Videos" library of the root web of that site collection. A copy of the video is sent to Azure Media Services which then transcodes it so that it can be played from a number of devices. Since the video is stored in SharePoint Online, the size of the video counts against your Tenant storage.

Since each video channel is a site collection, you can use the REST API to get all sorts of information about the channel including the list of videos.

So this is a channel called "Development" on my Office 365 Video Portal. You can see that there are 3 videos uploaded to this channel:


In order to get the list of videos in a video channel, we need to make a REST call to the SharePoint Search REST API:

_api/search/query?querytext='SiteTitle:"Development" AND ContentTypeId:0x010100F3754F12A9B6490D9622A01FE9D8F01200F9B0E79C5EBC0545B80F5F1B3985E159'&selectproperties='Path,Title,SiteTitle'

The ContentTypeId is the id of the new "Cloud Video" content type and the SiteTitle will be the name of the Channel.

Here is the complete code. I have used JavaScript and the jQuery.ajax function to make calls to the SharePoint REST API. But you can use a variety of other options like the JSOM, CSOM or even the Office 365 APIs. Since all the channels are by default open to users in the tenant, there should not be any major challenges to authentication around this. I haven't tested the code for these APIs myself.



And the logs in my Dev tools console:


Thanks for reading!

Get all documents from an Office 365 Group with REST

In my previous post, we saw how you can get a list of all the groups in your Office 365 portal with the REST API. Now, if you are building a solution on top of the Office 365 platform and want a list of all the documents in a particular Office 365 Group, you can get them using the REST API.

As discussed in my previous post, each group is underpinned by a separate site collection in SharePoint Online. When you upload a document to a group, it gets uploaded in the "Documents" library of the root web of that site collection. So you can use the REST API to get all sorts of information about the group including the list of documents. 

Here is a test group called "Technical Team" I have created in Office 365 for the purpose of this post. I have also uploaded 2 documents to it:



In order to get the list of documents in the group, we need to make a REST call to the SharePoint Search REST API:

_api/search/query?querytext='SiteTitle:"Technical Team" AND ContentTypeId:0x0101007DB6FD427B6228409ED888DF766B27C9'&selectproperties='Title,Path,SiteTitle'

The ContentTypeId is the id of the content type which is associated to the document when a document is uploaded to an Office 365 group.

Here is the complete code. I have used JavaScript and the jQuery.ajax function to make calls to the SharePoint REST API. But you can use a variety of other options like the JSOM, CSOM or even the Office 365 APIs. Since all the groups are by default open to users in the tenant, there should not be major challenges to authentication around this. I haven't tested the code for these APIs myself. 


And the logs in my Dev tools console:



Thanks for reading!