Monday, 17 August 2015

SharePoint online - Scenario to Re-index a site or list

Recently I was working with Search on a custom list in SharePoint online where I observed that not all the list items that fulfill a criteria are being returned in search results. Initially, I had created a custom list named "News" with the following fields

- Title
- Teaser
- Description.

I created 2 list items which were picked up by the continuous crawl in SP online and were being fetched properly in search results. Then I realized that I do not have a field that indicates when this news should be published to the user. So I added a new column "Publish Date" to the list, edited the 2 existing items to assign the Publish date and also created 4 new items.

In order to use the publish date field in search, I mapped it to an existing managed property and tried to query these items on a specific criteria for the PUBLISH DATE field using content search webpart. Though all the 6 items were satisfying the criteria, only the 4 NEW items created were being returned by the search. I gave it some time hoping that the SP online full crawl might index the two items, but it did not !

I then remembered the new feature in SharePoint 2013 which allows us to Re-Index a list, library or a site. Thought I would give it a shot. To re-index a list, go to the List Settings -> Advanced Settings  there is an option to re-index the list.

This will fully re-index the entire list. I also came across this article later which explains that re-index is required after changing the managed properties.

Friday, 14 August 2015

MIME type mismatch issue in SharePoint hosted app

Recently while working on a SharePoint hosted app, I encountered an issue where the App page was not loading correctly. The SharePoint hosted app was hosted on a site collection under the managed path "/sites" as in the following:

The reason I mention the site collection URL is because the issue is specifically related to it.This SP hosted app was a custom ribbon action made available on custom lists and on click of this action, the app page was being displayed in a dialog box. I observed that the UI of the app page was broken and it was apparent that some JavaScript/CSS references were missing.

Error displayed in the IE developer toolbar is shown below.

The SharePoint JavaScript files SP.runtime.JS and init.js were failing to load with the error "MIME 
type mismatch". Using the "Network" tab in the IE developer toolbar, I captured the page load network trace.

Shoot up the IE developer toolbar. Select the Network tab, click Start capturing and Trigger the app from ribbon. Then, let the page load and click "Stop capturing". 

Observe the type of sp.runtime.js. It was returned as "text/html".  My first guess was to check the MIME type values in the IIS website of the SharePoint web application. However, the type configured for JS files was "application/javascript". Also, the type returned for my custom JS files was "application/javascript", so only the JS files from "_layouts" failing to load properly!
The same app was working perfectly in another web application! Notice the URL from where the JS is loaded:

I tried to hit this URL in the browser. For the web application where the app was working, I got a prompt to save the file. For the web application where the app was not working, I did not get any response. So the path from where the JS was being loaded was incorrect or did not exist. !!

The issue was that the web application, where app was not working, did not have a site collection at the "/"  managed path. Creating this root site collection at the "/" path resolved the issue.

Hope this helps.

Thursday, 6 August 2015

SharePoint 2013 Work Management Service with Client API

The Work Management Service application was one of the new service applications introduced in SharePoint 2013. This service provides functionality to aggregate tasks from several locations into a central location in SharePoint. With the Work Management Service, we can aggregate tasks from SharePoint sites, an Exchange Server and Project Server into the user's My Site so that the user can see all the tasks assigned in one place. It also provides an API for developers to write custom components.
Consider you are working on an Intranet portal site. This service can be very helpful to write a component that sits on the home page of the portal site and displays all the tasks assigned to the logged in user.

We cannot use the Work Management Service API from a SharePoint APPS (at least now, as I am writing this article). I tried to use it in a provider hosted app but got an error that specified the Work Management Service assembly does not support app authentication.

Let us start by setting up all the required things for the Work Management Service.
From Central Administration select Application Management -> Manage Service Application then create a new "Work Management Service Application".

Make sure that the "Work Management Service" is started.

I have created two site collections with Test data.

The following are task lists in the two sites respectively.

Now navigate to your Profile page (Person.aspx) by clicking "OneDrive" of your SharePoint site and you will see a "Tasks" link in the left navigation.

Alternatively, navigate to the following URL: "/personal/USERID/AllTasks.aspx". In the tasks list, you'll see the combined list of tasks from both the SharePoint sites we created for testing.

Working with the API
We will the use of the client API of the Work Management Service to retrieve information related to our tasks. In work management terminology, "LOCATIONS" are the places where the tasks are stored. Let us try to retrieve the locations using the client-side object model. For demo purposes, I am writing the code in a console application.
Make sure you have all the DLL references in place.

The WorkManagement client DLL can be found in the "15/ISAPI" folder.Then we create a ClientContext and an instance of UserSettingsManager to retrieve the locations information.


Wednesday, 5 August 2015

Retrieve single-select Managed Metadata field Using REST API

A while ago I came across this very interesting piece of information of properly retrieving a single-select managed metadata column value.
The following is the reference of the article:Taxonomy Columns & REST API
Let us first try to fetch the value of a managed metadata column that allows adding multiple values to it. I have created a simple taxonomy term set called "Countries".

A custom list that contains a column "Country" that is a Managed Metadata column and allows multiple values to be added

The list contains the following values for testing:

Now we try to fetch the list items from this list using the REST API from the provider-hosted app. To use the REST API from the provider hosted app, we need to send the access token in the REST request. This will be used by SharePoint to authorize the call.

We have written the JSON response on our page and we can see that the label of the taxonomy field is retrieved properly.

Now If I change the managed metadata setting to single-select, we see the following difference:

 To retrieve this value properly, we need to make use of the GetItems method and SPQuery in the REST request.

And the value will be properly retrieved.

SharePoint 2013 High trust provider hosted app : Upload large files

Consider a situation where you want to allow a user to upload a large document in your SharePoint application, however the user does not have contribute permission to the Document Library. This can be for several reasons. You don't want the user to see/modify other content and only provide an interface to submit documents. 

We will use the app-only policy of provider hosted apps to upload the documents to the HOST web. This article assumes you understand the basics of the procedure to setup the environment and develop Provider-Hosted apps. If not, here is a technet article to follow.

I have created a provider hosted app with a client web part. The client webpart will be added to a page in the host web that will show a File upload control. The page that the client webpart shows will be deployed to the remote web of the provider hosted app. In this case, it is FileUpload.aspx.

Now, we need to tell the app to use the app-only policy when calling into SharePoint. With the app-only policy, irrespective of what level of permission the user has on the SharePoint site, only the app's permissions will be considered for authorization of the call. So, we set the value in the AppManifest.xml file of the provider hosted app. 

Also, since we are uploading a file in Document Library, the app needs to have the correct permissions on the SharePoint site. This is also set in the AppManifest.xml file.


In the FileUpload.aspx page, I have designed a simple UI with a file upload control and a button to upload the document. We write the code to upload the file to a SharePoint Document Library on the event handler of the button click event.

We will use the SharePointContextProvider to get the SharePoint context and theCreateAppOnlyClientContextForSPHost since we are using the app-only policy and uploading the file to the Host web. 


Using the "ContentStream" property, we can upload files of large size in the SP Document Library. Refer to: 

Now I have packaged and deployed my remote web in IIS and uploaded the app to my app catalog. I have also added the app to my SharePoint site. Edit the page and insert the client web part to a page in the Host Web.

And the client webpart shows the upload control and button. Please excuse the alignment of controls. :) 

Try to upload a large document (say about 80 MB, which I tried), and you may run into the below error

"The request filtering module is configured to deny a request that exceeds the request content length" 

This is because the IIS is configured to handle requests of only a specific size and since we are uploading a file of about 80 MB, it fails. We can change that using the web.config file. In the web.config of our remote web application, set the following values:

There is one more setting required. Open IIS then navigate to your remote web site. Click on "Request Filtering" . Click on "Edit Feature Settings" and change the value of "Maximum allowed content length".

Now we are all set. Select a document in the file upload control and hit Upload. Our file is uploaded and is modified by the APP because we are using the App-only policy.