Pages

Tuesday, June 12, 2012

SharePoint 2010: Updating Field Properties and Event Receivers in Custom Content Types

If you are working with custom content types in SharePoint 2010, you may face a situation where you need to update properties of existing fields after the content type has been deployed. In my experience, once the custom content type has been deployed and referenced in a list or document library and is currently in use, you CANNOT update field information through feature upgrade. Field information, however, will be updated in new document libraries or list when you add content type to it.

Updating Field Properties
You have two options if you want to update properties of existing fields in custom content types:

  1. Delete the content type from the document library or list and add it again. This might not be an ideal solution if you have items in your SharePoint list.
  2. Use PowerShell.
  3. Use a 64-bit console program referencing Microsoft.SharePoint.dll and System.Configuration.dll in order to update field information. The code snippet is provided below. Notice that I am using a for loop instead of foreach loop when accessing document libraries and content types in the document library. The foreach loop will throw a collection has been modified exception.

    using System;
    using System.Collections.Generic;
    using Microsoft.SharePoint;
    using System.Configuration;
    namespace UpdateSPFieldInfo
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (SPSite currentSite = new SPSite(ConfigurationManager.AppSettings["SP_SITE_URL"]))
                {
                    //I am interested in document libraries only where I am using my custom content type
                    SPListCollection docLibraryColl = currentSite.OpenWeb().GetListsOfType(SPBaseType.DocumentLibrary);
                    //You have to use a for loop. The foreach loop will cause an exception saying collection has been modified
                    for (int docLibCount = 0; docLibCount < docLibraryColl.Count; docLibCount++)
                    {
                        for (int ctCount = 0; ctCount < docLibraryColl[docLibCount].ContentTypes.Count; ctCount++)
                        {
                            if (docLibraryColl[docLibCount].ContentTypes[ctCount].Name == "HDSDocumentContentType")
                            {
                                Console.WriteLine("Document Library:" + docLibraryColl[docLibCount].Title);
                                string fieldsToUpdate = "CustomField1,_x0033_CustomField2";
                                foreach (string fieldInternalName in fieldsToUpdate.Split(','))
                                {
                                    SPField spField = docLibraryColl[docLibCount].Fields.GetFieldByInternalName(fieldInternalName);
     
                                    if (spField == null)
                                    {
                                        Console.WriteLine("The field \"" + fieldInternalName + "\" could not be found");
                                    }
                                    else
                                    {
                                        spField.ShowInDisplayForm = false;
                                        spField.ShowInEditForm = false;
                                        spField.ShowInNewForm = false;
                                        spField.Update();
                                        Console.WriteLine("The field \"" + fieldInternalName + "\" has been updated");
                                    }
                                }
                                break;
                            }
                        }
                    }            
                    
                }
     
                Console.ReadLine();
            }
     
            
        }
    }

Updating Event Receiver Association
If you have added a new event receiver to your content type, it will not be added to the existing list or document library where you have already added the event receiver. In order to update the event receiver association, you have to do the following:



  1. Get the assembly full name. This can be done by starting Windows PowerShell and typing the following command:
    [System.Reflection.AssemblyName]::GetAssemblyName("Path_To_Event_Receiver.dll").FullName

    image
  2. Get the event receiver class name in the form of Namespace_Name.class_name from your project.
  3. Add the following code to the program that is updating content type information:



    string AssemblyFullName = "MyCustomContentType, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1188765594dd1cac";
    string assemblyClassName = "MyCustomContentTypeNameSpace.ClassName";
    string delERName = "ItemDeleting";
    SPEventReceiverDefinitionCollection eventReceivers = docLibraryColl[docLibCount].EventReceivers;
    //If you want to retreive existing event receiver information
    foreach (SPEventReceiverDefinition sped in eventReceivers)
    {
          Console.WriteLine("Event Receiver Class:" + sped.Class.ToString());
          Console.WriteLine("Event Receiver Name:" + sped.Name);
    }
    //Example of an ItemDeleting event receiver
    SPEventReceiverDefinition delER = eventReceivers.Add();
    delER.Name = delERName;
    delER.Type = SPEventReceiverType.ItemDeleting;
    delER.SequenceNumber = 2;
    delER.Assembly = AssemblyFullName;
    delER.Class = assemblyClassName;
    delER.Update();
     
    Console.WriteLine("Event Receiver Added");



No comments:

Post a Comment