A while ago I did a series of blog posts about Taxonomy Fields. You can find those posts here: Part I, Part II, Part III. Most of the code in those posts is not usable when working in the Sandbox, since the Microsoft.SharePoint.Taxonomy namespace is not available when writing solutions for the sandbox.

 

The other day I had to write a solution for a customer which had (among others of course) the following requirements:

- Centrally managed content types

- Sandboxed Solution

- Automated Install

 

I decided to create a Sandboxed Content Type Hub that would contain my Site Columns and Content Types.

 

All this will be deployed to the SharePoint Farm using PowerShell Scripts. This gives me some flexibility to configure my Taxonomy Fields using PowerShell. The solution to declaring Taxonomy Fields described in my earlier post http://www.insidesharepoint.net/post/2010/11/05/Using-taxonomyfields-in-Sharepoint-2010-Part-I.aspx uses a Feature Receiver to connect the declared Taxonomy Field to its hidden notefield and to the Term Set from the TermStore. In order to do this, we need classes from the Microsoft.SharePoint.Taxonomy namespace that are not available in the Sandbox. So I couldn’t use that solution directly.

 

What I eventually did was declare the fields as usual in the solution, and then rewrite the feature receiver to a PowerShell function. Also I wrote scripts to create the Content Type Hub site collection and to upload the Sandboxed Solution containing my Content Types and Site Columns to the Content Type Hub site collection. I thought I share the code to do this with you, maybe it helps someone out there.

 

Wiring up a Taxonomy Field using PowerShell:

 

function ConfigureMetaDataField( [string]$taxFieldGuid, [string]$noteFieldGuid, [string]$siteUrl, [string]$mmaName, [string]$groupName, [string]$termSetName ) 
{
    # Get the site
    $site = Get-SPSite $siteUrl

    # Get the taxonomy field that was deployed by the Sandboxed WSP
    [Microsoft.SharePoint.Taxonomy.TaxonomyField]$field = $site.RootWeb.Fields | Where-Object { $_.Id -eq $taxFieldGuid }
    
    # Set the hidden note field
    $field.TextField = $noteFieldGuid

    # Get the correct Term Set from the Managed Metadata service app
    $session = new-object Microsoft.SharePoint.Taxonomy.TaxonomySession($site)
    $termstore = $session.TermStores[$mmaName]
    $group = $termstore.Groups | Where-Object { $_.Name -eq $groupName }
    $termSet = $group.TermSets[$termSetName]

    # Set the fields termstore id and termset id
    $field.SspId = $termstore.Id
    $field.TermSetId = $termSet.Id

    # Update the field

$field.Update()

 

# Dispose

$site.Dispose()

}
 

The PowerShell function assumes that you have already deployed the Taxonomy Field and its hidden note field using a (Sandboxed) WSP. How to do this is described in my earlier post here, but reprinted here for completeness:

 

Fields declaration:

 

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">  
	<Field Type="TaxonomyFieldTypeMulti"          
		DisplayName="MyTaxonomyField"          
		ShowField="Term1033" Required="TRUE"          
		ID="{8D0458C1-0FB7-4981-BEE1-52D0DF01895C}"          
		StaticName="MyTaxonomyField"          
		Name="MyTaxonomyField"          
		Group="Custom"         
		Mult="TRUE"         
		>
	</Field>    
	<Field Type="Note"          
		DisplayName="MyTaxonomyField_0"          
		StaticName="MyTaxonomyFieldTaxHTField0"          
		Name="MyTaxonomyFieldTaxHTField0"          
		ID="{3a913424-fc7f-49ef-8fb6-a2ca1712cdc3}"          
		Hidden="TRUE"         
		DisplaceOnUpgrade="TRUE"         
	/>
</Elements>
 

ContentType declaration:

 
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Item (0x01) -->
  <ContentType ID="0x0100b58d33764b384da58bbadee9721e1843"
               Name="MyCustomContentType"
               Group="Custom"
               Description="Custom provisioned contenttype containing a Taxonomyfield"
               Inherits="TRUE"
               Version="0">
    <FieldRefs>
      <FieldRef ID="8D0458C1-0FB7-4981-BEE1-52D0DF01895C" Name="MyTaxonomyField"/>
      <FieldRef ID="3a913424-fc7f-49ef-8fb6-a2ca1712cdc3" Name="MyTaxonomyFieldTaxHTField0"/>
      <FieldRef ID="f3b0adf9-c1a2-4b02-920d-943fba4b3611" Name="TaxCatchAll"/>
      <FieldRef ID="8f6b6dd8-9357-4019-8172-966fcd502ed2" Name="TaxCatchAllLabel"/>
    </FieldRefs>
  </ContentType>
  <Receivers>
    <Receiver>
      <Name>TaxonomyItemSynchronousAddedEventReceiver</Name>
      <Type>ItemAdding</Type>
      <Assembly>Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
      <Class>Microsoft.SharePoint.Taxonomy.TaxonomyItemEventReceiver</Class>
      <SequenceNumber>10000</SequenceNumber>
    </Receiver>
    <Receiver>
      <Name>TaxonomyItemUpdatingEventReceiver</Name>
      <Type>ItemUpdating</Type>
      <Assembly>Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
      <Class>Microsoft.SharePoint.Taxonomy.TaxonomyItemEventReceiver</Class>
      <SequenceNumber>10000</SequenceNumber>
    </Receiver>
  </Receivers>
</Elements>
  

Uploading the Sandboxed Solution (WSP) to the Content Type Hub Site Collection:

 

Add-SPUserSolution -LiteralPath $wspPath -Site $siteUrl

 

Activating the Sandboxed Solution:

 

Install-SPUserSolution -Identity SolutionName.wsp -Site $siteUrl

 

Activate the Content Type Feature using the commandlet Enable-SPFeature.

 

This feature automatically activates the Site columns feature. If you make the Site Columns feature hidden and you create an activation dependency between the Content Type feature and the Site Columns feature, the Site columns feature will automatically be activated when activating the Content Type Feature. Pretty neat.

 

Calling the PowerShell function:

 

ConfigureMetaDataField -taxFieldGuid "8D0458C1-0FB7-4981-BEE1-52D0DF01895C" -noteFieldGuid "3a913424-fc7f-49ef-8fb6-a2ca1712cdc3" ‘

-siteUrl "http://mycontenttypehub" -mmaName "My Managed Meta Data Service Application" -group "MyGroup" -termSet "MyTermSet"

 

Thats it! Hope this helps someone…

Read from Source