How to read SharePoint Managed Metadata Look-up (Taxonomy Field) value using Client Object Model?

The below Console Application code explains you how to read SharePoint Managed Metadata Look-up (Taxonomy Field) value using Client Object Model.

using System;
using System.Text;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Taxonomy;

namespace CSOMRnD
class Program
static void Main(string[] args)

using (ClientContext context = new ClientContext(“SiteURL”))
context.ExecutingWebRequest += new EventHandler(clientContext_ExecutingWebRequest);
context.AuthenticationMode = ClientAuthenticationMode.Default;
context.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

List list = context.Web.Lists.GetByTitle(“ListName”);

CamlQuery query = new CamlQuery();

query.ViewXml = “pass your query”;

ListItemCollection items = list.GetItems(query);

foreach (ListItem item in items)
StringBuilder sb_ProductFieldValue = new StringBuilder();

TaxonomyFieldValueCollection taxProductFieldValueColl = item[“Product”] as TaxonomyFieldValueCollection;

if (taxProductFieldValueColl != null)
foreach (TaxonomyFieldValue taxProductFieldValue in taxProductFieldValueColl)
if (taxProductFieldValue.Label.Trim() != null)
sb_ProductFieldValue.Append(taxProductFieldValue.Label + “|”);

static void clientContext_ExecutingWebRequest(object sender, WebRequestEventArgs e)
e.WebRequestExecutor.WebRequest.Headers.Add(“X-FORMS_BASED_AUTH_ACCEPTED”, “f”);


How to use taxonomy hidden field?


In one of our SharePoint list we have more than 10 look-up columns with managed metadata type. One fine day our UAT SharePoint site went very low and the CPU utilization in DB Servers associated with the UAT farm started increasing up to 80%. At this point of time the total number of UAT users involved in testing are only 4 to 7. We have around 25k+ terms stored under different terms sets.

When we started investigating we found that below key points

1) CAML query calls coming from the custom pages to get managed metadata column values are the most expensive queries on the DB server side.

2) This behavior is happening only when we access those particular custom pages for the first time after an IIS reset.

We all know SharePoint will take more time when we load anything after IIS Reset. But it should not consume more CPU and get into deadlock situation.

Imagine the situation if we move this code to production with 10 to 15 concurrent users? The whole UAT SharePoint farm users and shared resources will be affected because of the CAML Query Issue after any IIS reset.


When we approached MS, they suggested “Every taxonomy field of the item should have a hidden field together; e.g. with the Category (taxonomy) field, there should also be a hidden field named something like Category_0 (in my farm), try to use this field in the view fields instead and see if it will improve the results. The reason is that the hidden field is not a lookup field that it shouldn’t need to do any follow up queries to SQL but 1 single query should do the job. Note that the hidden field doesn’t just contain the value that it will also contain the Taxonomy ID, so after getting the value of the hidden field, you will need to parse it to extract the field value. But this should minimize the queries sending to SQL.”

When we modified our CAML queries with the hidden column, we found that the CPU utilization is not increasing and the site performance also very decent.

I am not sure is there any better way to improve this. If you have any ideas / feedback please let me know.

Important Note:
The timer job which updates the taxonomy look-up column will not update this hidden column until there is a change in the item where it is looked-up. We were informed by MS that they are working on this issue.

To validate the hidden column names, I am using SharePoint 2013 Client Browser tool

Sample JavaScript Code

var siteUrl = ‘/’;

var listfld_Product;
var listfld_Release;

var listfld_Product_str;
var listfld_Release_str;

var Inputstr = ‘Product A’;

function retrieveInternalNames()
var clientContext = new SP.ClientContext(siteUrl);
var oList = clientContext.get_web().get_lists().getByTitle(‘CA_Product_Master_List’);

listfld_Product = oList.get_fields().getByTitle(“Product_0”);
listfld_Release = oList.get_fields().getByTitle(“Release_0”);


clientContext.executeQueryAsync(function ()
listfld_Product_str = listfld_Product.get_internalName();
listfld_Release_str = listfld_Release.get_internalName();

function (sender, args)
alert(‘Request failed. ‘ + args.get_message() + ‘\n’ + args.get_stackTrace());
catch (err)

function retrieveListItems()
var clientContext = new SP.ClientContext(siteUrl);
var oList = clientContext.get_web().get_lists().getByTitle(‘CA_Product_Master_List’);

var camlQuery = new SP.CamlQuery();

camlQuery.set_viewXml(“<View><ViewFields><FieldRef Name=’” + listfld_Product_str + “‘ Type=’Notes’/><FieldRef Name=’” + listfld_Release_str + “‘ Type=’Notes’/></ViewFields><Query> <Where> <BeginsWith> <FieldRef Name=’” + listfld_Product_str + “‘ /><Value Type=’Notes’>” + Inputstr + “|” + “</Value> </BeginsWith> </Where> </Query></View>”)

this.collListItem = oList.getItems(camlQuery);
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
catch (err)

function onQuerySucceeded(sender, args)
var listItemInfo = ”;
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext())
var oListItem = listItemEnumerator.get_current();

var releaseArray = oListItem.get_item(listfld_Release.get_internalName()).split(‘;’);
var rleaseInfo = ”;
for (var i = 0; i < releaseArray.length; i++)
rleaseInfo += releaseArray[i].split(“|”)[0] + “;”

listItemInfo += oListItem.get_item(listfld_Product.get_internalName()).split(“|”)[0] + ‘
‘ + rleaseInfo + ‘

document.getElementById(‘div_Prod_Data’).innerHTML = listItemInfo;

function onQueryFailed(sender, args)
alert(‘Request failed. ‘ + args.get_message() + ‘\n’ + args.get_stackTrace());


O365 Custom JavaScript Injection using PowerShell

Custom action fetches an external script and includes it in the page. So at run time the script will self execute as an anonymous function.

Following are few scenarios you may need this functionality in your SharePoint Projects:

1) Override the new sub site link ( under Site Contents  with your site provisioning app URL

2) Redirect the user to specific page

3) Inject third-party JavaScript libraries such as Jquery, Knockout, AngularJs, etc.,

4) Add dynamic html (global navigation / company copy rights information on the bottom of your page) content on your sharepoint page at run time without even modifying the actual master page.

In the below example, I have explained how to inject Jquery file to one of my web. The source files can be placed in CDN / File Share / Common Location such as App Catalog.

Please feel free to change the logic as per your requirement.

Note: The logic remains same for JSOM code also.


O365 / SharePoint Online – Apply Theme – CSOM & PowerShell

As you know, Web.ApplyTheme method applies a theme with the specified components to this site.

For more information refer –

Here fontSchemeUrl and backgroundImageUrl parameters can accept null values. But when I tried to pass $null or null or Empty String to these two parameters via PowerShell, I got the following error:

“Exception calling “ApplyTheme” with “4” argument(s): “The ‘fontSchemeUrl’ argument is invalid.”.Exception.Message”

Then i tried with Out-Null instead of $null or null or Empty String. Trust me it worked like a charm.

Actually the Out-Null cmdlet deletes output instead of sending it down the pipeline.

This is my final code.

Hope this helps.




Connect SharePoint Framework Apps with Office 365 Service Endpoints using Office Graph APIs

As you aware, SharePoint Framework 1.4.1 supports MSGraphClient.

MSGraphClient is used to perform REST calls against Microsoft Graph. The Microsoft Graph JavaScript client library is a lightweight wrapper around the Microsoft Graph API. This class allows developers to start making REST calls to MSGraph without needing to initialize the the MSGraph client library.

Note: Microsoft Graph API is replacing the previously released GraphHttpClient, which is now considered to be deprecated.

In this post, I am going to show you a SharePoint Framework WebPart to fetch my User Profile details using Microsoft Graph API. I consider that you have a SharePoint Framework HelloWorldWebPart WebPart, if you don’t, take a look at this article.

Note: API Management can be performed only on first release tenant.

  • Import the MSGraphClient in the HelloWorldWebPart.ts file as shown below


  • Write the following code snippet inside the render function.


  • Open the package-solution.json file and update the Graph API permission


  • Update the CDN cdnBasePath parameter in write-manifests.json file as per your setup
  • Execute the gulp bundle and gulp package-solution with ship attribute to prepare the build
  • Upload the CDN files in the CDN location specified in the write-manifests.json file
  • Upload the SPPKG file in the app catalog site. As shown below, We have to approve the Microsoft Graph API permission requested by the developer in the package-solution.json.


  • Click Deploy
  • Open the New SharePoint Admin Center and click on API Management
  • Select the permission and approve the request


  • Install the HelloWorld WebPart in a SharePoint Site and add the same in a page
  • Verify if HelloWorld WebPart is printing the current user display name and mail in browser console.

Searching SharePoint Results from Windows Explorer using OSDX and Custom RSS File


SharePoint 2013 Enterprise Search with Windows 7 Operating Systems


To understand what is a OSDX file and how to add an OSDX file as a search provider in Windows Explorer please refer the below links:


When I use the OOB SharePoint RSS file to show the results in the windows explorer I was not able to map the custom managed properties to the windows attributes such as Summary,  thumbnail, etc.,

The OOB SharePoint RSS file located in the following location:


Regarding this issue, when I approached some MVPs and Microsoft Windows Development team they replied that it is not possible to map the SharePoint managed properties with the windows explorer search result attributes.

Some of the articles are also explaining the same

So what is the solution for this?


Windows 7 is the first OS with the capability to use external search providers as federated search locations – and yes, this federated location can also be SharePoint!  In general, all search providers can be federated if it’s OpenSearch 1.0/1.1 compatible or, in other words, can provide the search results in RSS/Atom format.

So that means if I have to create my own RSS feeding file then my custom code should return the SharePoint search results in RSS/Atom format. So I started exploring what is the best way to get the search results. Then I found a interesting feature in SharePoint 2013 called “SharePoint 2013 Search REST API”. This new REST service is the best way to go in a variety of application scenarios. External Applications to SharePoint that require search functionality can also leverage this service as the endpoint for communication into the Search platform. The old search.asmx SOAP web service is marked as deprecated in SP2013, and the new Search REST service is the replacement.

Location of the Search Rest service

The Search REST service is located at the following URI: http://host/site/_api/search

See more about this from the below link

Using the above mentioned API I am supplying the keyword to the API and getting the XML output. From the XML output I am extracting the necessary XML Node values and populating the output in the format of RSS/Atom using the below code:

Front end Code

<%@ Page Language=”C#” AutoEventWireup=”true” CodeBehind=”SearchAppliedRSS.aspx.cs” Inherits=”SearchResultsRSS.Layouts.SearchResultsRSS.SearchAppliedRSS” ContentType=”text\xml” %>

<asp:Repeater ID=”ResultRSSRepeater” runat=”server”>


<rss version=”2.0″>



<link>Configure you site URL</link>


Nucleus Search Center Site.





<title><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Title”)) %></title>

<link>Item URL</link>

<description><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Description”))%></description>

<category><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Category”)) %></category>

<pubDate><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “LastModifiedTime”))%></pubDate>

<author><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Author”))%></author>








Back end Code

protected void Page_Load(object sender, EventArgs e)


string keyword = Request.QueryString[“keyword”];

string query = “http://<Site Name>/_api/search/query?querytext='” + keyword + “‘&sourceid=’c9a51276-5b58-423c-88cb-a64297974cb4’&selectproperties=’Author,TCItemType,TCItemName,Description,LastModifiedTime'”;

WebRequest req = WebRequest.Create(query);

NetworkCredential myCred = new NetworkCredential(“<Admin Account User ID>”,”Password”,”Domain Name”);

req.Credentials = myCred;

WebResponse resp = req.GetResponse();

System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());

// process response..

XDocument oDataXML = XDocument.Load(sr, LoadOptions.None);

XNamespace atom = “”;

XNamespace d = “”;

XNamespace m = “”;

List<XElement> items = oDataXML.Descendants(d + “query”)

.Elements(d + “PrimaryQueryResult”)

.Elements(d + “RelevantResults”)

.Elements(d + “Table”)

.Elements(d + “Rows”)

.Elements(d + “element”)


// Extracting the values from XML..

DataTable dt = new DataTable();






foreach (XElement item in items)


DataRow dr = dt.NewRow();

//XElement xItem = item.Element(d + “Cells”).Descendants(d + “Key”).First();

foreach (XElement xItem in item.Element(d + “Cells”).Descendants(d + “Key”))


if (xItem.Value == “TCItemName”)


dr[“Title”] = xItem.Parent.Element(d + “Value”).Value;


else if (xItem.Value == “Author”)


dr[“Author”] = xItem.Parent.Element(d + “Value”).Value;


else if (xItem.Value == “Description”)


dr[“Description”] = xItem.Parent.Element(d + “Value”).Value;


else if (xItem.Value == “LastModifiedTime”)


dr[“LastModifiedTime”] = xItem.Parent.Element(d + “Value”).Value;


dr[“Category”] = “Teamcenter Item”;




// data-bind to ListView..

ResultRSSRepeater.DataSource = dt;



protected string RemoveIllegalCharacters(object input)


// cast the input to a string

string data = input.ToString();

// replace illegal characters in XML documents with their entity references

data = data.Replace(“&”, “&amp;”);

data = data.Replace(“\””, “&quot;”);

data = data.Replace(“‘”, “&apos;”);

data = data.Replace(“<“, “&lt;”);

data = data.Replace(“>”, “&gt;”);

return data;


Finally instead of configuring the SharePoint OOB search RSS file, I have configured the customized RSS Feed file which I have created using the above code in the OSDX file.

How to create RSS?

Now I am able to see the results with the format I have specified in the code. Please see the below screen:

Load alternate image if there is an error in the configured image URL – IMG Tag


We have a SharePoint BCS Profile page (with XSLT customization). In this page we have to load an image in one of the column/cell. There is no problem in loading the image with the IMG tag until the image is not available. If the image is not available in the given URL, it will normally show the cross mark (X) symbol.

The customer requirement is below:

If the image is not available in the given URL location then show an alternative image / text (Preview not Available).


By adding the below tag you can overcome this issue

<img src=”<Image URL>” alt=”” onError=”this.src=<Alternate Image URL>’/>

We have to be very cautious when we use this code. The browser will be stuck in an endless loop if the onError alternate image itself gives an error in loading. So to avoid this use the below code

<img src=”<Image URL>” alt=”” onError=”this.onerror=null;this.src=<Alternate Image URL>’/>

Displaying Current User Display Name in SPD Custom Forms

  • Open the custom page in Advanced Mode using SharePoint Designer
  • Find the section of the page where “ParameterBinding” are set. Add this new entry:  <ParameterBinding> Name = “LogonUser” Location = “ServerVariable(LOGON_USER)” />
  • Next search for “XSL:Param name”, and add this line: <xsl:param name=”LogonUser”/>
  • Now to display the value in the form use the below tag where ever you want: <xsl:value-of select=”$LogonUser”/>

Redirecting SPD NewForm.aspx to other pages with the Current Item ID as Query String

Business Need

We have a site request SharePoint List. Users will raise request using this list to get a new SharePoint WIKI article. Once the user press the Save button in the OOB SharePoint Designer form (which we customized using SPD 2010), it should redirect to one Status Page and wait there till the workflow creates the new site and configure the permission based on the meta data submitted by the requestor.

Once the workflow is completed we have to check the status of the workflow. If the status of the workflow is “Success” then we have to redirect the page to the newly created site. If the status is “Failed” then we have to show an alert message.


Basically in SPD forms once the data is submitted, the page will be redirected to the page where you came from.

The problem here is to identify the ID of the newly created item and check the workflow status using that ID since the ID for the new item is unknown before the item has been created


To solve this we have to follow the below steps explained in the below article :


First Open the customized New / Edit form in SPD 2010 and override the SharePoint default save buttons with the HTML input buttons

<input type=”button” value=”Save” name=”btnSave” onclick=”javascript: {ddwrt:GenFireServerEvent(‘__commit;__redirect={/Sites/<Site Name>/<Library Name>/GetLastID.aspx?RedirectURL=/Sites/<Site Name>/<Library Name>/WIKIStatus.aspx}’)}” />

Note: Replace the Site Name and Library Name with your details

Now create an intermediate page (GetLastID.aspx) and paste the below code then upload this in any of your document library of your site.  All this page does is find the most recent item in the list which was created by the current user and redirect to WIKIStatus.aspx with the ID on the Query String (ParaID).

<%@ Page Language=”C#” inherits=”Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<%@ Register Tagprefix=”SharePoint” Namespace=”Microsoft.SharePoint.WebControls” Assembly=”Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<%@ Register Tagprefix=”Utilities” Namespace=”Microsoft.SharePoint.Utilities” Assembly=”Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<%@ Import Namespace=”Microsoft.SharePoint” %>

<%@ Register Tagprefix=”WebPartPages” Namespace=”Microsoft.SharePoint.WebPartPages” Assembly=”Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>


<head runat=”server”>

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>



<form id=”form1″ runat=”server”>

<WebPartPages:DataFormWebPart runat=”server” IsIncluded=”True” FrameType=”None” NoDefaultStyle=”TRUE” ViewFlag=”0″ Title=”Events” __markuptype=”vsattributemarkup” __WebPartId=”{020AF483-2135-4D37-B6C7-CD6A6FD6AF5D}” id=”g_a8a4d070_e7c0_4105_a113_acff9dea3328″ pagesize=”1″ __AllowXSLTEditing=”true” WebPart=”true” Height=”” Width=””>


<SharePoint:SPDataSource runat=”server” DataSourceMode=”List” UseInternalName=”true” selectcommand=”<View><Query><Where><Eq><FieldRef Name=&quot;Author&quot;/><Value Type=&quot;Integer&quot;><UserID/></Value></Eq></Where><OrderBy><FieldRef Name=&quot;Created_x0020_Date&quot; Ascending=&quot;FALSE&quot;/></OrderBy></Query></View>” id=”dataformwebpart2″>


<WebPartPages:DataFormParameter Name=”ListName” ParameterKey=”ListName” PropertyName=”ParameterValues” DefaultValue=”Test List”/>





<ParameterBinding Name=”UserID” Location=”CAMLVariable” DefaultValue=”CurrentUserName”/>

<ParameterBinding Name=”RedirectURL” Location=”QueryString(RedirectURL)” DefaultValue=””/>


<datafields>@Title,Title;@Start_x0020_Time,Start Time;@End_x0020_Time,End Time;@ZIP_x0020_Code,ZIP Code;@Amount,Amount;@Nominee,Nominee;@ID,ID;@ContentType,Content Type;@Modified,Modified;@Created,Created;@Author,Created By;@Editor,Modified By;@_UIVersionString,Version;@Attachments,Attachments;@File_x0020_Type,File Type;@FileLeafRef,Name (for use in forms);@FileDirRef,Path;@FSObjType,Item Type;@_HasCopyDestinations,Has Copy Destinations;@_CopySource,Copy Source;@ContentTypeId,Content Type ID;@_ModerationStatus,Approval Status;@_UIVersion,UI Version;@Created_x0020_Date,Created;@FileRef,URL Path;</datafields>


<xsl:stylesheet xmlns:x=”” xmlns:d=”” version=”1.0″ exclude-result-prefixes=”xsl msxsl ddwrt” xmlns:ddwrt=”” xmlns:asp=”″ xmlns:__designer=”” xmlns:xsl=”” xmlns:msxsl=”urn:schemas-microsoft-com:xslt” xmlns:SharePoint=”Microsoft.SharePoint.WebControls” xmlns:ddwrt2=”urn:frontpage:internal”>

<xsl:output method=”html” indent=”no”/>

<xsl:param name=”UserID”>CurrentUserName</xsl:param>

<xsl:param name=”RedirectURL” />

<xsl:template match=”/” xmlns:x=”” xmlns:d=”” xmlns:asp=”″ xmlns:__designer=”” xmlns:SharePoint=”Microsoft.SharePoint.WebControls”>

<xsl:call-template name=”dvt_1″/>


<xsl:template name=”dvt_1″>

<xsl:variable name=”Rows” select=”/dsQueryResponse/Rows/Row”/>

<xsl:for-each select=”$Rows”>

<xsl:call-template name=”dvt_1.rowview” />



<xsl:template name=”dvt_1.rowview”>

document.location.href = '' +

"?ParaID=" + '';








Note: Replace “Test List” with your list name

Now create a new page and name it as “WIKIStatus” and add the below script in a CEWP. All this CEWP page does is check the status of the workflow for the Item Id received from the Query String.  If the value of the status column is “Success” then it will redirect the page to the newly created site (which was updated by the workflow behind the scene). If the status is “Failed”, then it will show an alert message.

ExecuteOrDelayUntilScriptLoaded(runCode, “sp.js”);

var itemId = querySt(“ParaID”);   // Query String

var targetListItem;

function runCode()


var clientContext = new SP.ClientContext();

var targetList = clientContext.get_web().get_lists().getByTitle(‘Test List’); // Change the List Name here

targetListItem = targetList.getItemById(itemId);

clientContext.load(targetListItem, ‘Status’, ‘SiteURL’); // Select the column names here

clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));


function onQuerySucceeded()


if(targetListItem.get_item(‘Status’) != “Completed” || targetListItem.get_item(‘Status’) != “Failed” )




if(targetListItem.get_item(‘Status’) == “Completed”)


document.location.href = targetListItem.get_item(‘SiteURL’);


if(targetListItem.get_item(‘Status’) == “Failed”)


alert(“Please contact the administrator.”);



function onQueryFailed(sender, args)


// alert(‘Request failed. \nError: ‘ + args.get_message() + ‘\nStackTrace: ‘ + args.get_stackTrace());

alert(‘Request failed. \n Contact Admin ‘);


function querySt(Key)


var url = window.location.href;

KeysValues = url.split(/[\?&]+/);

for (i = 0; i


1)      Replace “Test List” with your list name

2)      “Status” and “SiteURL” are the two columns iam refereing from my site request list

That’s it you are done 🙂 . Thank you Marc for the idea you have explained in your article.