Thursday, 14 February 2013

SharePoint 2013: Provision AppPart/ClientWebPart to Page

Along with Apps, SharePoint 2013 has introduced App Parts (ClientWebParts) which give you the functionality of placing the app inside and iframe on a page. This way, you can view your app as a part of the page just like you would a normal webpart.

(The terms App Part and Client Web Part are interchangeable. I will be using both the terms in this post to emphasize the similarity)

Adding an App Part to the page from the SharePoint User Interface is pretty easy. You just put the page in edit mode and add the AppPart from the Insert Menu. Pretty similar to how you would add a regular WebPart.

Now what if you have to provision your AppPart in a Page or a PageLayout so that when a new page is created with a feature, your AppPart is automatically placed on that page?.

If you want to know how to add an app part to a page declaratively through the Elements.xml file, please have a look at my post here:
http://vrdmn.blogspot.in/2013/03/sharepoint-2013-declaratively-add-app.html


Lets look at how it can be done:

First and foremost, you will need to create an AppPart (Client WebPart) for your app. Here is a great tutorial on it:
http://msdn.microsoft.com/en-us/library/fp179921.aspx

Your Client WebPart xml file should be similar to this:


Here, I have created a Client Web Part with 2 Properties of type int and enum respectively.

Second, you have to make sure that your app is already installed on the Web on which you will be provisioning your page. The AppPart will only work if the app is installed on the same web.

Next, you will need the ProductId of your app. Here is how to find it:

1) Open your app in Visual Studio -> Right Click on the AppManifest.xml -> View Code


2) Here you will find the ProductId of your app in the following location:


3) Save your ProductId in a convenient location.

4) Now open your Page or Page Layout and add the following code to it:


In FeatureId, enter the ProductId which we got from the app earlier.

In ProductWebId, create a new random GUID and add it. 

You can even set default values for the App Part Properties.

5) That's It, Now deploy your page and see that the App Part is Provisioned on the Page.

Sunday, 3 February 2013

SharePoint 2013: Working with User Profiles & JavaScript CSOM

SharePoint 2013 has added a variety of functionality to the Client API. One of them is the ability to fetch User Profile data. Now you can directly query the user profiles and get the required data from the client site. This can be really useful if you are building apps.

If you want to use the REST API to work with user profiles, please see one of my other posts: http://www.vrdmn.com/2013/07/sharepoint-2013-get-userprofile.html

In this post, I will show you how to work with User Profiles using the JavaScript Client Object Model

Before we get started with the code, lets make couple of things sure. First,  you will need a reference to the following JavaScript files in your page:


(jQuery is not required but I have added it because we will need it for the $.ajax function when doing REST queries)

Second thing, you will need the domain\username of the user you want to get the user profile data for. This can be easy to get if you are in an On-Prem environment. But if you are working with SharePoint Online, this can be quite tricky. Your username might not always be in the domain\username format. It is stored in the LoginName property if you are querying the Site User Information List:

https://yoursite.sharepoint.com/sites/pubsite/_api/Web/GetUserById(17)

and it is stored in the AccountName property if your querying the User Profile Service:

https://yoursite.sharepoint.com/sites/pubsite/_api/SP.UserProfiles.PeopleManager/GetMyProperties

In SharePoint Online, it will most probably be in the following format:

i:0#.f|membership|vardhaman@yoursite.onmicrosoft.com


Quick Note: If you are using the REST API, you will need to encode the username before you use it in your call. The encodeURIComponent( ) function can be helpful here.

Enough talking. Lets jump into some code right away:

1) Get Multiple User Profile Properties:



2) Get Single User Profile Property:



3) Get User Profile Properties of the Current User:



4) Get Properties of Multiple Users in Single Request:



For this last example, Let's observe the XML which is sent to the server:



With this, we can confirm that only one call was made to the server to retrieve the properties of multiple users. This way, you can even retrieve multiple properties of multiple users in one call.

Tuesday, 29 January 2013

SharePoint 2013: Elevate User Access with App Only Policy

In SharePoint 2013 Apps, the authorization is handled by a 2 part mechanism. Along with the current user's permissions, the app permissions are also taken into account. User permissions and app permissions are two separate entities which dictate whether an app is allowed to perform a certain action.

When you build an app, you can specify that what all permissions are going to be required for the app to run successfully. You have to specify this in the App Manifest under the Permissions tab.

(Click Image to Zoom)



When a user installs an app, he can only grant permissions to the app up to the level which he has. So if a user has "Read" permissions on a list, he cannot grant the app "Full Control" on the same list.



There are basically 3 types of app authorizations or authorization policies in SharePoint 2013.

1) User Only Policy: In this policy, only the user permissions are taken into account. App permissions are ignored. It is checked whether the user has the permissions to perform the action and if yes, then he/she is allowed to perform the action.

2) App + User Policy: The user as well as the app permissions are taken into account. This is an AND operation. If both the user and the app have the permission to perform the action,only then the action is allowed.

3) App Only Policy: Only the permissions granted to the app are taken into account. User permissions are ignored. So even if the current user accessing the app does not have appropriate permission, the action is allowed provided the app has the permission to do so.

The App Only policy works by using a separate OAuth token which runs under the user "SHAREPOINT/App" much like SPSecurity.RunWithElevatedPriviledges() runs under the "SHAREPOINT\System" user (app pool account) in the Server Object Model.

Since OAuth is required to generate the app token, the App-Only policy can only be used in the Auto-hosted and Provider-Hosted apps. SharePoint-Hosted apps cannot use the app only policy.


To enable the App Only policy in your app, you have to add the "AllowAppOnlyPolicy" attribute to your "AppPermissions" element in the App Manifest:



Note: Although you can add this attribute to the App Manifest of the SharePoint-Hosted apps, it will be ignored as the App Only policy is not supported in SharePoint hosted apps.


Enough chit chat, lets see how we can actually utilize the App Only policy to elevate user permissions. I have written the following code in the code behind of the Default.aspx of an Auto-Hosted App:


As you can see, the ClientContext which is opened with the appOnlyAccessToken will run with the identity of the SHAREPOINT\App account. This is a very good practice to remember even when using RunWithElevatedPreviledges in the Server Object Model. You can switch on/switch off database calls with app only token. This means that if you need to make only one operation with the elevated token, then you can do that and get back to using the current user's token in one action.

Saturday, 12 January 2013

Authenticating .NET CSOM in SharePoint Online

The process of authenticating the .NET Client Object Model in SharePoint Online has been greatly simplified in the 2013 version. Earlier (2010), you had to go through a lot of steps for doing the exact same thing. You  had to open a web browser instance, force the user to enter the credentials in the browser and then grab that  cookie from Internet Explorer and pass it to the .NET CSOM. If you are interested, the code of the old authentication method can be found here:
http://blogs.msdn.com/b/cjohnson/archive/2011/05/03/authentication-with-sharepoint-online-and-the-client-side-object-model.aspx

Fortunately in the 2013 version, the process is a lot simplified by the introduction of the SharePointOnlineCredentials class. This class is part of the Microsoft.SharePoint.Client.dll itself so you don't have to include an extra assembly in your application. All you have to do is pass an instance of the SharePointOnlineCredentials class to the ClientContext.Credentials property. The SharePointOnlineCredentials takes in two parameters which are your Login Email for your Office 365 SharePoint site and your password in the SecureString format.

You can grab all the required SharePoint 2013 client assemblies from here:
http://www.microsoft.com/en-us/download/details.aspx?id=35585

For this particular demo, you will need to reference the Microsoft.SharePoint.Client.dll and the Microsoft.SharePoint.Client.Runtime.dll assemblies in your project.

 The code is as follows:




Wednesday, 19 December 2012

Working with Taxonomy and JavaScript in SharePoint 2013

SharePoint 2013 has introduced some nice new features, one of which is the ability to manipulate managed metadata with the JavaScript Object Model. Unlike SharePoint 2010, we can now do a variety of operations with the Taxonomy Items in SharePoint 2013. Unfortunately, at the time of this writing, there is not a lot of documentation available on MSDN with regards to this particular feature.There is some preliminary documentation available for the Taxonomy in .NET Managed Client Object Model but the JavaScript API Reference has not been updated yet. So hopefully this blog will come in handy for someone looking to explore. All right lets get started:

First and foremost, you will have to load the SP.Taxonomy.js on your page explicitly as it is not loaded by default in SharePoint. Also make sure that you have loaded the SP.Runtime.js and SP.js files before continuing with your taxonomy code. Various errors like "SP.Taxonomy is not defined" or "Unable to get property 'TaxonomySession' of undefined or null reference" might come up if you have not loaded all the 3 necessary files on your page.

A simple way to load all the 3 files is with the jQuery.getScript function:



Now lets see some actual code which you can use to Manipulate the Taxonomy Items:

1) Query a particular Term Set and get all the Terms under it:




2) Create new Term Group under the Term Store:




3) Create new Term Set under a Term Group:




4) Create new Term under a Term Set:




5) Get Value of a Single Value Taxonomy Column in a List:




6) Get Values of a Multi Value Taxonomy Column in a List:




Hopefully you found this helpful. Happy SharePointing!

Saturday, 3 November 2012

Querying List Items from Large Number of Sites in SharePoint


When scouting the web for working with SharePoint Large Lists, you can find many articles which deal with fetching a huge number of items from one particular list. But very little data when you want to fetch items from a large number of sub sites. So after a little bit of poking around, I decided to blog about some of my findings here:

The Scenario:

Here are the conditions on which I was testing:
  • 1 Site Collection
  •  500 Sub sites
  •  1 Task List in Each sub site - > 500 Lists
  •  10 items in each List -> 5000 List Items

 So the total count of items I had to query was about 5000 and according to the test conditions, the items which would match the query were not more than 1200 at a time.

The Tools:

The tools I was using for measuring the performance were nothing extraordinary:

1)  I was using the StopWatch Class from the System.Diagnostics namespace. This class provides a fairly simple and easy mechanism for recording the time a particular operation took to execute.
This MSDN link has excellent examples on how to use the StopWatch class for performance measuring

2) The Developer Dashboard has always been my goto tool for performance measuring. I don’t know how I used to get by before I started using it. It provides a wealth of information about the page load. It can provide you with the time taken, the database calls made, the stack trace and a whole lot of other very useful information. A good tutorial on the Developer Dashboard can be found here.

SPSiteDataQuery:

The SPSiteDataQuery class is the heart of architecture when you want to get data from multiple sites. This class by itself does not use any form of caching and always returns data based on the real time queries. So even if it takes a bit longer to fetch the data, it is guaranteed that you will get all the current results and your users will never have to wait to see their new items to be returned by the query.

Here is the code for doing a simple query with the SPSiteDataQuery class:


Here is a stack trace of the internal methods which are called by the SharePoint framework when a SPSiteDataQuery is used:


So as you can see, it calls the SPRequest.CrossListQuery method which internally makes queries to the Database to fetch the relevant results.

When querying the database the procedure proc_EnumListsWithMetadata is used. You can have a look at this procedure in your Content DB. It queries several tables such as the dbo.AllLists, dbo.AllWebs etc. to fetch the relevant results.

Time taken to query 5000 items in 500 sub sites and return 1200 matching items:

 650ms average on each load.

CrossListQueryInfo:

The CrossListQueryInfo class is another mechanism you can use to fetch the List Items from multiple sites. This class internally uses the SPSiteDataQuery class to actually fetch the items from the database and when the items are returned, it stores them in the object cache of the Publishing Infrastructure. When any more calls to the same data are made subsequently, then the data is returned from the cache itself without making any more trips to the database.

The working of the CrossListQueryInfo class largely depends on the object cache of the Publishing Features of SharePoint server. So you cannot use this class in SharePoint 2010 Foundation or in sandbox solutions. Also, the default expiry time of the object cache is set to 60 seconds. So you might want to change that time depending upon your environment requirements.

Here is the same code for using the CrossListQueryInfo class:


Make sure to set the CrossListQueryInfo.UseCache as true if you want to use the caching features. Another very important thing to mention is that there are 4 overloads of the CrossListQueryCache.GetSiteData method and only 2 of them support caching.
So only use the methods which accepts the SPSite object as one of the parameters if you want to use caching in your code.
The Stack Trace of the CrossListQueryInfo class looks like this:


So as you can see, the Publishing.CachedArea is queried first to check whether the items exist in the cache. If they don’t exist, then a call to the SPSiteDataQuery is made which fetches the values from the database and stores it in the cache. All the next subsequent calls will find that the items are present in the cache so no more calls with the SPSiteDataQuery class will be made.

As a result, the very first call will take longer than a vanilla SPSiteDataQuery call as under the hood, the CrossListQueryInfo is not only fetching the items but also building a cache with them.

Time taken to query 5000 items in 500 sub sites and return 1200 matching items:
 2000ms on first load and 30ms average on each subsequent load until the object cache expires.

PortalSiteMapProvider:

The PortalSiteMapProvider is a class which can used to generate the navigation on SharePoint Publishing sites. The Global navigation, the Quick Launch and the Breadcrumb navigation can all be generated with help of the PortalSiteMapProvider. It also provides methods to query sub sites, lists and list items with help of caching.

The main advantage of the PSMP is that it queries the SharePoint change log to check whether any changes have happened to the data being queried. If yes, then only the incremental changes are fetched and thus the cache is updated accordingly.

However, my tests showed that the PortalSiteMapProvider.GetCachedSiteDataQuery method which is used to get items from multiple sub sites does not maintain an incremental cache and it only fetches the new or updated items when the object cache has expired.

So essentially when querying for items from multiple sites, the CrossListQueryInfo and the PortalSiteMapProvider behave almost similarly.

Here is the sample code for the PortalSiteMapProvider:


The stack trace for the PortalSiteMapProvider:


You can see that it’s very similar to the CrossListQueryInfo.

Time taken to query 5000 items and return 1200 matching items:
 2000ms on first load and 30ms average on each subsequent load until the object cache expires



So these are some of the methods you can use to query multiple List Items in multiple sites. Hope you had a good time reading through the post. 

Happy SharePointing!