Inherits Cloud

Loving Microsoft Cloud, specially Office 365

Deploying Managed Metadata Fields declaratively in SharePoint 2013 Online (Office 365)

In this article, we will see how we can deploy Managed metadata fields in a declarative way in SharePoint online, showing a new and different approach than in Farm solutions (the old way).

Basically this approach tries to cover the needed of deploying Managed metadata fields from a custom web template using a Sandbox solution. As you probably know, if you want to do this in a farm solution, you will find yourself following this post from Wictor Wilen (http://www.wictorwilen.se/Post/How-to-provision-SharePoint-2010-Managed-Metadata-columns.aspx). This is perfect for a Farm solution, but is not a valid approach for Sandbox solutions and Office 365 because the Microsoft.Sharepoint.Taxonomy.dll is not allowed. Apparently, the only option that we have is to create the Managed Metadata fields using the UI (or maybe some others imaginative solutions with remote events and client code), but if our solution is a custom web template that will be used to create new site collections, that means that the user has to create all the Managed metadata fields for every site collection… sounds not good!

However, Wictor shows us some interesting things about the Schema of a Managed metadata field, that we also see using SharePoint Manager from a Managed metadata field created from the SharePoint UI.

Here is the complete Schema XML of a Managed metadata field created manually:


Let’s see the values that we need to focus on:

Key/Attribute

Description

ID

Any GUID

Type

TaxonomyFieldType (field with a single value)/ TaxonomyFieldTypeMulti (field with multiple terms)

Name

Name of the field

StaticName

Static name (usually the same as name)

DisplayName

Display name that will show in the UI

List

Value setted by SP when deploys the field. We can skip this attribute

WebId

Value setted by SP when deploys the field. We can skip this attribute

ShowField

Term1033 (Term + LCID that we are using)

Requiered

Mandatory field

EnforceUniqueValues

Only one list item with this value in the field?

Group

Group to show the field in the UI

SourceID

Value setted by SP when deploys the field. We can skip this attribute

Version

Value setted by SP when deploys the field. We can skip this attribute

SspId

GUID of the Managed Metadata Service Application

TermSetId

GUID of the TermSet you want to bind the field

Open

true/false (user can insert new values, only if the TermSet is defined as open)

TextField

GUID of the Hidden Note field

There are 3 values that we have no control over them:

· SspId: when you create an Office 365 tenant (you buy it), the Managed metadata service application is created with a name like: “Taxonomy_Zz2Z7zzzZzZzzzzZZzz2zz==” and a GUID. Obviously this value is different from each tenant y we don’t have any control on it.

We can see the GUID from the UI:

image

· TermSetId: This GUID is assigned when you create a new TermSet. If we create the TermSet manually, we can’t set this GUID. However, as we will see later, we can deploy our Term Store including TermSets and Term, specifying the GUID. So, let’s say that this value will be well-known for us.

· TextField: When SharePoint creates a MM field, actually is creating 2 fields, one is the MM field with the Schema showed above, but it creates a second Field of type Note, and a Hidden field. Again, using SharePoint Manager we can see a field, that usually has the same name as the MM field, but adding a “_0”

image


The Schema of the Hidden Note field is:


So we can deploy this hidden Note field in our sandbox solution, and that way, the TextField value will be a well-known value as well.

Note: When SharePoint deploys the Elements.xml file with our 2 fields: MM and Note field, it follows a sequential order, for this reason, is a requirement that the Note field is before in the Elements.xml than the Taxonomy field. If not, when SP create the Taxonomy field, he won’t find the TextField ID because is not provisioned yet. You won’t get an error, but SP will create its own Note field, and the Taxonomy field will not be mapped correctly.

The only field that we can’t assign by ourselves and will change from one Office 365 tenant to other is the SspId, but later will talk a little more about it.

Now, we are going to see how we can deploy our Taxonomy, and set fixed GUIDs for TermSets and Terms. To achieve this, I think the best approach is to write some CSOM code in a power shell script, which we will run as a part of the deployment. I usually work with a Taxonomy xml file created using the Power Shell commands from Gary Lapointe (http://blog.falchionconsulting.com/index.php/downloads/). That way, you can create all your taxonomy in your local environment, and later, export it to an XML file, that will be deployed in the Office 365 tenant using CSOM.

The next code is not complete but shows the path that you can follow to create TermSets and Terms using CSOM inside PowerShell:

# Get the password as a SecureString and load the client libraries

$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force

Add-Type -Path "c:Program FilesCommon Filesmicrosoft sharedWeb Server Extensions15ISAPIMicrosoft.SharePoint.Client.dll"

Add-Type -Path "c:Program FilesCommon Filesmicrosoft sharedWeb Server Extensions15ISAPIMicrosoft.SharePoint.Client.Runtime.dll"

Add-Type -Path "c:Program FilesCommon Filesmicrosoft sharedWeb Server Extensions15ISAPIMicrosoft.SharePoint.Client.Taxonomy.dll"

# Get the client context

$context = New-Object Microsoft.SharePoint.Client.ClientContext($url)

$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user, $securePassword)

$context.Credentials = $credentials

# Get the Taxonomy Session and first Term store

$taxonomySession = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($context);

$taxonomySession.UpdateCache();

$context.Load($taxonomySession);

$context.ExecuteQuery();

$termStores = $taxonomySession.TermStores

$context.Load($termStores)

$context.ExecuteQuery()

$termStore = $termStores[0]

$context.Load($termStore)

# Create a Group

$group = $termStore.CreateGroup($name, $groupGuid);

$context.Load($group);

$context.ExecuteQuery();

# Create a Term Set

$termSet = $group.CreateTermSet($name, $id, $termStore.DefaultLanguage);

# Create a Term

$term = $termSet.CreateTerm($name, $lcid, $id);

Well, as I said before, we still have a disadvantage. If we have different environments and Office 365 tenants (test, production…) we have to change manually the SspId before creating the WSP file in every Managed metadata field, which can be hard in some scenarios, but remember, in my opinion is still better than force the user to create all the Taxonomy fields manually on each site collection. Anyway, I’m so lucky for working with Chris O’brien who has solved this inconvenient using MSBuild, and I’m sure will blog about it very short. I will update this article linking Chris’ blog.

Hope it helps, and let me know any comment.

Luis Manez

@luismanez

Deja un comentario

Tu dirección de correo electrónico no será publicada.

*

© 2024 Inherits Cloud

Tema por Anders NorenArriba ↑