Provider Hosted App – Upload Large Files using CSOM

We all at some time struggled with uploading large files using CSOM in O365. Using managed client object model, we can upload a maximum of 2MB file size. If the file is of larger size, we usually had two options:

  1. File.SaveBinaryDirect
  2. Using REST which supports upto 2GB

The first option can not be used in Sharepoint Online because SaveBinaryDirect does not work with claims authentication (check this link). Does that mean we are left with REST only? Actually NO. We have one more way by which we can upload files greater than 2MB in O365 using CSOM in provider hosted app. But let’s first see the standard CSOM way which allows us 2MB file upload.

Now the method to upload larger files is exactly the same. We only have to use FileCreationInformation.ContentStream property instead of FileCreationInformation.Content property. The whole code is present below:

In some cases, you might get a FileNotFoundException while using above code. Below is another way to use the code

Note that I replaced FileStream with the input stream present in the uploaded file itself.

P.S. I have tested the above code for files upto 50 MB. It depends largely on internet speed. Once for 50MB file size it gave me time out error (which could be fixed by setting RequestTimeout property of client context)

Hope this helps.

Reference:

  1. O365 AMS
Advertisements

Unique Identifier for O365

Multi-tenant apps are a very common scenario in real world. Whenever we create an app, we mostly target it to multiple tenants for wider reach. There are some cases in which we want to save our app data in custom database instead of app web or host web. These scenarios are very frequent and at that time we need a unique identifier to differentiate among tenants. So my search started for a pre-existing identifier of O365 and ended right at TokenHelper.cs file.
Yes, Microsoft has already provided a code for it, I just didn’t realize it’s a unique identifier. 🙂

In TokenHelper.cs there is a public method GetRealmFromTargetUrl(Uri targetApplicationUri) that takes URI of the target sharepoint site as its parameter. This method actually return a string representation of the realm GUID. According to msdn,

 Realm is unique to each tenant in Office 365 or to each SharePoint farm on-premises. It is possible to discover the realm at run time. So, it is not necessary to cache this information between requests, but it will cost you an extra round trip to SharePoint each time you want to look it up. If you use code similar toTokenHelper.GetRealmFromTargetUrl with the site URL, and cache the result per site (or even per site and per user), you can use this later without making the extra call.

For more details, visit this link.

Therefore, above method return a unique id for tenant. You can pass host web uri in it. This id can be saved in database for further use and can even be cached.

Source code for this method is given below. This is copy pasted from TokenHelper.cs class which Visual Studio auto-generates on creating provider hosted app.

 


public static string GetRealmFromTargetUrl(Uri targetApplicationUri)
{
WebRequest request = WebRequest.Create(targetApplicationUri + "/_vti_bin/client.svc");
request.Headers.Add("Authorization: Bearer ");

try
{
using (request.GetResponse())
{
}
}
catch (WebException e)
{
if (e.Response == null)
{
return null;
}

string bearerResponseHeader = e.Response.Headers["WWW-Authenticate"];
if (string.IsNullOrEmpty(bearerResponseHeader))
{
return null;
}

const string bearer = "Bearer realm=\"";
int bearerIndex = bearerResponseHeader.IndexOf(bearer, StringComparison.Ordinal);
if (bearerIndex < 0)
{
return null;
}

int realmIndex = bearerIndex + bearer.Length;

if (bearerResponseHeader.Length >= realmIndex + 36)
{
string targetRealm = bearerResponseHeader.Substring(realmIndex, 36);

Guid realmGuid;

if (Guid.TryParse(targetRealm, out realmGuid))
{
return targetRealm;
}
}
}
return null;
}

 

Hope this helps. 🙂

Knockout.js with Sharepoint 2013 App – Part III

In my previous post, we saw how to add items in a SP list using KO. This post will focus on removing items from a list. The code snippet at the end combines all the three posts. Using it; you can display, add and remove items from list. Besides that we send only updated (i.e. added or removed) data to server side. Going on the same lines, we can implement the “edit” functionality also. Right now, I am skipping it.

For reference, the other two posts are:

  1. Part I – Displaying Data from SP list. 
  2. Part II – Adding Data to SP list.
  3. Part III – Removing Data from SP list. (this one)

To add remove functionality, a “Remove this” link is added after every row in the table. So, the html looks like:

KO-Remove-1

$root.RemoveCountries will update the view model. Here $root is the main view model in the topmost/parent context. It will update the whole table by removing the current row.

“Id” column of sharepoint list is also included in the “CountryList” class to delete items by id. For newly created rows the id is assigned to ‘0’. After every update to the server, the “changedCountries” array is emptied.

The final result will look like,

KO-Remove-2

Now, the final collaborated code is:

 

Note: In sharepoint hosted app, we do not need SP.RequestExecutor.js to communicate with host web that means cross-domain calls to host web is allowed without this javascript file. The code is updated for this.

Summary: KO is an amazing library that makes life easier by segregating the display logic with the business logic. Using it in SP, makes the js code neat and simple to understand. The only flip side is, if there are changes at the server side, then UI is not automatically updated until a refresh is performed. Regardless of this, KO is a library we all should learn.

P.S.: This example is by no means perfect or bug free. There are few loopholes like:

  1. User can edit the existing items but this is not handled in the code.
  2. After adding a new item to SP list the view model is not updated unless user do a refresh.
  3. Only 20 items are fetched and no pagination is implemented.

But the code is for demo purpose only. You can extend it in any way you want. Hope it helps!!

Another good blogs on KO (also referenced here):

  1. Knockout.js Simplified
  2. Using Knockout.js in a sharepoint context

Knockout.js with Sharepoint 2013 App – Part II

In my previous post, we saw how to display items from a sharepoint list using KO. In this post, we will see how to add items in the list. This demo is in continuation with the previous one.

For your reference, the posts in this series are:

  1. Part I – Displaying Data from SP list. 
  2. Part II – Adding Data to SP list. (this one)
  3. Part III – Removing Data from SP list.

First, lets go through the changes made in the previous code for incorporating this functionality.

HTML Changes:

  1. A button “Add State” is added. This button updates the view model and add a new country-state in the existing table. It does not update the SP list.
  2. Another button “Submit to Sharepoint” is added. This button actually updates the data in the sharepoint list.
  3. Now the country and states are displayed in text box so that user can add new ones. Edit functionality is not included in this post.
  4. Two divs are added for displaying success and failure messages.

CSS Changes:

  1. styling is added for success and failure messages. Not much changes are done here.

Javascript Changes:

  1. Another property “IsUpdated” is added in  the “CountryList” class. This property is used to keep tab of newly created items in the view model. Using this, we will send only changed items to the server and not the complete list of data.
  2. In the view model, “UpdateSPList” function is added. This function will be called on click of “Submit to SP” button.
  3. “changedCountries” array holds all the newly added items. “emptyValues” is a boolean variable which maintains if any of the country name or state name is blank. If yes, then that entry is not sent to SP and a message is displayed to the user.
  4. “SubmitDataToSP” is a function which actually uses sharepoint CSOM and adds new items in the list.
  5. On click of “Add State” button a function “AddCountries” of view model is called. The parameters passed are $data (which is the current item inside a foreach loop), country name, state name and true as the value of “IsUpdated” property. For more details on ‘click’ event, check this link.
  6. Similarly on click of “Submit to SP” we call, “UpdateSPList” method of the view model.

So, now the complete code is as follows:

The result page will look like:

result

Note:

Please note that this might not be the completely optimized way to achieve this functionality. The goal here is to demo use of KO with sharepoint. In the next post, we will modify this code further to achieve delete functionality.

Hope this helps!!

Knockout.js with Sharepoint 2013 App – Part I

Knockout.js is an amazing javascript library for binding data and generating html at run time. It uses MVVM pattern that is Model-View-ViewModel pattern. This post assumes that you have a basic understanding of knockout and sharepoint client side object model. If not, then go through the amazing set of tutorials present in knockout (KO) site.

I was recently introduced to KO and found it amazing. But I didn’t find much on how to implement it in sharepoint context. So, I decided to look into it and  share with you all my learnings of KO with sharepoint. This post is dedicated to just displaying data from a list in a page using KO. Further posts will focus on adding and removing data too. At the end, we will see if KO is actually a good option for sharepoint or not. The post in the series will be:

  1. Part I – Displaying Data from SP list. (this one)
  2. Part II – Adding Data to SP list.
  3. Part III – Removing Data from SP list.

To start I am using sharepoint 2013 app model. A sharepoint hosted app is created for displaying list’s data in html page present in app context. The structure of the list is:

List for knockout Demo

This is a simple list which contains names of country and their states. Using KO we will display this in a table structure. KO makes the client side code simple and easier to use. HTML, CSS and JS all files are separate and manageable.

So the code for displaying this data is :

The output page will look like:

KO output 1

This is how we use KO in sharepoint. Notice the object oriented structure of “App.js”.  The code is relatively very clean and easy to understand. In next post we will add items in a list using KO. Hope this helps.

Sitemaps in SharePoint 2013

In sharepoint 2013, we have native support for generating xml sitemaps which was not present in the earlier versions of sharepoint. Sitemaps basically inform the search engines about the pages and their metadata, present in your site. This help the crawlers in picking up those pages. This is a great feature especially for public facing websites.

The steps to generate sitemap are straightforward but nowhere I found complete documentation on it. So to begin with, there are three prerequisites for generating sitemap:

  1. This feature is available for publishing sites only.
  2. Anonymous access should be enabled for both web application and site collection.
  3. Search should be configured in the environment.

The step by step procedure to generate sitemap is:

  1. Enable anonymous access for web application.
    For this go to “Central Admin” -> “Manage Web Applications” . Select your web application and click on “Authentication Providers” in top ribbon.
    Click on the zone. There you will get the option to enable anonymous access.
    AnonymousAccessWebApp
  2. Enable anonymous access for site collection.
    Go to “Site Settings” -> “Site permissions”. Click on “Anonymous Access” in the top ribbon and select “Entire Web site”. Click “OK”
    Anonymous Access Site Collection
  3. Activate “Search Engine Sitemap” feature of site collection. This registers a timer job “Search Engine Sitemap Job” for generating sitemap. This job by default runs daily.
    Site collection feature
  4. As sitemap generation uses Search Service to generate sitemap; run full crawl or incremental crawl as applicable to your environment.
    Go to “Central Admin” -> “Application Management” -> “Manage service applications” -> “Search Service”.
    Then click on “Content Sources” and run full/incremental crawl for your content source.
  5. For getting instantaneous result, run the timer job mentioned in step 4 for your web application manually.
  6. And we are done.

The sitemap is located at the root level site collection. The url to access the sitemap is http://<WebApp>/sites/<SiteColl>/sitemap.xml. This file contains the location of actual sitemap and that is http://<WebApp>/sites/<SiteColl>/sitemap0.xml. The content of the sitemap file is like:
Sitemap

Hope this helps.