Ali Mazaheri has posted a similar code recently, but since that was for content type, not list fields, and I found there are some minor difference between the two, I’ll post my solution for adding managed metadata type field to lists.
To tell the truth, I have not tried adding this kind of field to content type, but “translated” the code for handling the list fields instead, and extended with some new features.
I should note, that first I’ve tried to update the field either it was just added or was added previously, but I’ve received a <nativehr>0x80070057</nativehr><nativestack></nativestack> error when tried to update the newly added field. Probably it was because in this case the field had its Id and InternalName properties empty yet.
- AddTaxonomyField(SPList list, bool mayExist, String name, bool required, String description,
- bool addToDefaultView, bool noCrawl, String termStoreName, String groupName, String termSetName, String anchorPath,
- bool allowsMultiple, bool enforceUniqueValues)
- {
- SPWeb web = list.ParentWeb;
- TaxonomySession session = new TaxonomySession(web.Site);
- TermStore termStore = session.TermStores[termStoreName];
- Group group = termStore.Groups[groupName];
- TermSet termSet = group.TermSets[termSetName];
- TaxonomyField field = null;
- bool fieldExists = false;
- // if we allow the field to exist ant it really exist
- // then we get the reference for the instance
- // it will throw an exception if the field exists
- // but has a different type
- if ((mayExist) && (list.Fields.ContainsField(name)))
- {
- field = (TaxonomyField)list.Fields[name];
- fieldExists = true;
- }
- // otherwise we create a new instance
- // it will throw an exception if the field exists
- // and we would like to recreate that
- else
- {
- field = (TaxonomyField)list.Fields.CreateNewField("TaxonomyFieldType", name);
- }
- field.Required = required;
- field.Description = description;
- field.SspId = termStore.Id;
- field.TermSetId = termSet.Id;
- field.AllowMultipleValues = allowsMultiple;
- field.EnforceUniqueValues = enforceUniqueValues;
- // field must be indexed to enfoce unique values!
- field.Indexed = enforceUniqueValues;
- if (!String.IsNullOrEmpty(anchorPath))
- {
- // see GetTermByPath method in my former post
- Term anchor = termSet.GetTermByPath(anchorPath);
- field.AnchorId = anchor.Id;
- }
- field.NoCrawl = noCrawl;
- if (!fieldExists)
- {
- list.Fields.Add(field);
- }
- else
- {
- field.Update();
- }
- if (addToDefaultView)
- {
- SPView view = list.DefaultView;
- // we add the field if it is new or if the view does not contain already it
- if ((!fieldExists) || (!view.ViewFields.Exists(field.InternalName)))
- {
- view.ViewFields.Add(field.Title);
- view.Update();
- }
- }
- return field;
- }
For the GetTermByPath method I used to get the value of the AnchorId property see my former post. Anchor is a term that refers to the Term that is the starting point of the “navigation” within a TermSet. Users can select only Term that are under the anchor Term.
Thanks Peter….
Comment by madhu Kashyap — March 27, 2012 @ 11:15