SharePoint 2013 CSOM Taxonomy (Managed Metadata)

SharePoint 2013 has introduced Microsoft.SharePoint.Client.Taxonomy.dll.   It means that we can do play with Taxonomy using client side object model instead of just relying on server side code. This dll is located at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\. Programming using CSOM is almost similar to server side object model.

The below code shows how to create Termsets, Groups, Terms.

  

 

publicclassSharePointWebContext : IDisposable

{

public Microsoft.SharePoint.Client.ClientContext SharePointClientContext = null;

public Microsoft.SharePoint.Client.Web Web = null;

publicstring Url = string.Empty;

protectedILog Log = LogManager.GetLogger(typeof(SharePointWebContext));

public SharePointWebContext(Microsoft.SharePoint.Client.Web web, string url)

{

this.Web = web;

this.Url = url;

}

public SharePointWebContext(string url)

{

this.Url = url;

this.SharePointClientContext = newClientContext(this.Url);

this.Web = this.SharePointClientContext.Web;

}

#region IDisposable Members

///<summary>

/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged

/// resources.

///</summary>

voidIDisposable.Dispose()

{

}

#endregion

}

 

 

 

 

 

[Description("Processes an XML string containing managed metadata terms, termsets and groups.")]

public class WebCreateTermsets

{

public WebCreateTermsets(Microsoft.SharePoint.Client.ClientContext context)

: base(context)

{ }

[Parameter(1, typeof(String), "SiteUrl", "The web url")]

[Parameter(2, typeof(String), "TermSetXmlData", "An XML string containing terms, termsets and groups")]

protectedoverridevoid OnExecute(paramsobject[] args)

{

try

{

string webUrl = GetParameter<string>(args, 1);

string xmlData = GetParameter<string>(args, 2);

TermStoreInfo termStoreInfo = TermStoreInfo.FromXml(xmlData);

using (var context = new SharePointWebContext(webUrl))

{

Microsoft.SharePoint.Client.Web web = context.Web;

TaxonomySession taxonomySession = TaxonomySession.GetTaxonomySession(web.Context);

TermStore termStore = taxonomySession.TermStores.GetByName(termStoreInfo.Name);

web.Context.Load(termStore);

web.Context.ExecuteQuery();

if (termStore == null)

{

Log.ErrorFormat("The Taxonomy Service is offline or unavailable.");

return;

}

CreateGroups(termStoreInfo, termStore, web);

}

}

catch (Exception x)

{

Log.Exception(x);

}

}

protectedvoid CreateGroups(TermStoreInfo termstoreInfo, TermStore termStore, Microsoft.SharePoint.Client.Web web)

{

if (termstoreInfo != null && termstoreInfo.Groups.Count > 0)

{

foreach (GroupInfo groupInfo in termstoreInfo.Groups)

{

TermGroup termGroup = default(TermGroup);

try

{

termGroup = termStore.Groups.GetByName(groupInfo.Name);

web.Context.Load(termGroup);

web.Context.ExecuteQuery();

}

catch (Exception)

{

termGroup = null;

}

if (termGroup == null)

{

termGroup = termStore.CreateGroup(groupInfo.Name, Guid.NewGuid());

termStore.CommitAll();

web.Context.ExecuteQuery();

}

CreateTermsets(groupInfo, termGroup, termStore, web);

}

}

}

protectedvoid CreateTermsets(GroupInfo groupInfo, TermGroup termGroup, TermStore termStore, Microsoft.SharePoint.Client.Web web)

{

foreach (TermSetInfo termsetInfo in groupInfo.TermSets)

{

TermSet termSet = default(TermSet);

try

{

termSet = termGroup.TermSets.GetByName(termsetInfo.Name);

web.Context.Load(termSet);

web.Context.ExecuteQuery();

}

catch (Exception)

{

termSet = null;

}

if (termSet == null)

{

termSet = termGroup.CreateTermSet(termsetInfo.Name, Guid.NewGuid(), 1033);

termStore.CommitAll();

web.Context.ExecuteQuery();

}

CreateTerms(termsetInfo, termSet, termStore, web);

}

}

protectedvoid CreateTerms(TermSetInfo termSetInfo, TermSet termSet, TermStore termStore, Microsoft.SharePoint.Client.Web web)

{

foreach (TermInfo termInfo in termSetInfo.Terms)

{

Term term = default(Term);

try

{

term = termSet.Terms.GetByName(termInfo.Name);

web.Context.Load(term);

web.Context.ExecuteQuery();

}

catch (Exception)

{

term = null;

}

if (term == null)

{

term = termSet.CreateTerm(termInfo.Name, 1033, Guid.NewGuid());

termStore.CommitAll();

web.Context.ExecuteQuery();

}

CreateTerms(termInfo, term, termStore, web);

}

}

protectedvoid CreateTerms(TermInfo termInfo, Term term, TermStore termStore, Microsoft.SharePoint.Client.Web web)

{

foreach (TermInfo childTermInfo in termInfo.ChildTerms)

{

Term childTerm = default(Term);

try

{

childTerm = term.Terms.GetByName(childTermInfo.Name);

web.Context.Load(childTerm);

web.Context.ExecuteQuery();

}

catch (Exception)

{

childTerm = null;

}

if (childTerm == null)

{

childTerm = term.CreateTerm(childTermInfo.Name, 1033, Guid.NewGuid());

termStore.CommitAll();

web.Context.ExecuteQuery();

}

CreateTerms(childTermInfo, childTerm, termStore, web);

}

}

 

protected T GetParameter<T>(object[] args, int parameterId)

 {

 if (args == null || parameterId > args.Length)

 returndefault(T); 

return (T)args[parameterId - 1];

 }

 

}

 

The input for this class is going to be in below format. The input is encoded xml.

 

 <SharePointCommands xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns="https://schemas.sharepointarchitects.com/caml.net/SharePointCommandSet.xsd">
 <Command Type="WebCreateTermsets">
 <Name>Caml.Net.SharePoint.Tools.Web.WebCreateTermsets</Name>
 <Description>Processes an XML string containing managed metadata terms, termsets and groups.</Description>
 <Parameters>
 <Parameter>
 <Name>SiteUrl</Name>
 <Type>System.String</Type>
 <Description>SiteUrl</Description>
 <Value>https://win-64t2uiim6ta/sites/TestBox</Value>
 </Parameter>
 <Parameter>
 <Name>TermSetXmlData</Name>
 <Type>System.String</Type>
 <Description>TermSetXmlData</Description>
 <Value>
 &lt;TermStore&gt;
 &lt;Name&gt;Managed Metadata Service&lt;/Name&gt;
 &lt;Groups&gt;
 &lt;Group&gt;
 &lt;Name&gt;Groupl&lt;/Name&gt;
 &lt;Termsets&gt;
 &lt;Termset&gt;
 &lt;Name&gt;Termset1&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level1Term&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level11Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level12Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level2Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Termset&gt;
 &lt;Termset&gt;
 &lt;Name&gt;Termset2&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level1Term&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level11Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level12Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level13Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level2Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level3Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Termset&gt;
 &lt;/Termsets&gt;
 &lt;/Group&gt;
 &lt;Group&gt;
 &lt;Name&gt;Group2&lt;/Name&gt;
 &lt;Termsets&gt;
 &lt;Termset&gt;
 &lt;Name&gt;Termset1&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level1Term&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level11Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level12Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level2Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Termset&gt;
 &lt;Termset&gt;
 &lt;Name&gt;Termset2&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level1Term&lt;/Name&gt;
 &lt;Terms&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level11Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level12Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level12Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level2Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;Term&gt;
 &lt;Name&gt;Level3Term&lt;/Name&gt;
 &lt;/Term&gt;
 &lt;/Terms&gt;
 &lt;/Termset&gt;
 &lt;/Termsets&gt;
 &lt;/Group&gt;
 &lt;/Groups&gt;
 &lt;/TermStore&gt;
 </Value>
 </Parameter>
 </Parameters>
 </Command>
 </SharePointCommands>
  
  
 Here is the output: