Wednesday, March 16, 2011

Copying Managed Metadata between site collections with code

I was recently writing an event handler on a list that was suposed to copy the contents of a list item form one site collection to another. The code was fairly simple except that the Managed Metadata columns would not copy.

My first attempt was to simply copy the value of the taxonomy field from one list item to another, this worked for all the other fields in question, so why not?

//targetItem and sourceItem are SPListItem type
targetItem["metaColumn"] = sourceItem["metaColumn"];

This didn't work. I then did a quick search and found (somewhere that I can't find now to give credit) that I had to use the SetFieldValue method of the TaxonomyField class to assign the value. Ok, so my next attempt was:

TaxonomyFieldValue value = (TaxonomyFieldValue)sourceItem["metaColumn"];
TaxonomyField taxTargetField = (TaxonomyField)targetItem.Fields.GetFieldByInternalName("metaColumn");
taxTargetField.SetFieldValue(targetItem, value);

This didn't work either. I suspect this would have worked if the two list items were in the same site collection.

The next attempt actually worked, and it went like this:

 TaxonomyField taxTargetField = (TaxonomyField)targetItem.Fields.GetFieldByInternalName("metaColumn");

TaxonomySession taxonomySession = new TaxonomySession(targetItem.Web.Site);
TermStore termStore = taxonomySession.TermStores["ManagedMetadataService"];

taxTargetField.SetFieldValue(targetItem, termStore.GetTerm(new Guid((sourceItem["metaColumn"] as TaxonomyFieldValue).TermGuid)));

The main point to notice here is that I had to create a new reference to the term, using the context of the target site. So it seems that setting the value of a taxonomy field requires using a Term or TaxonomyFieldValue that is fetched out of a TaxonomySession from the same site as the field itself.

2 comments:

Yuri said...

Exactly what I'm trying to do right now. Thanks a lot!

Kourosh said...

Hi,
I want to tell that I have solved it by creating Fields programmatically and same field on all site collections have same Guid. you need just copy file from list to another your Metadata will be copied.