Thursday, 28 February 2013

Associate custom content type to existing Document Libraries using feature event reciever

Associate  custom content type to existing Document Libraries using feature event reciever:-

Open “Empty SharePoint Project” in visual studio and later add “Content type” and “Empty Element” for site columns, by using Add->New Item option in solution explorer, as shown in below image



After adding xml for Content type and site column, right click Feature in solution explorer and add event receiver for the same



Open “Event Reciever” and create code as given below

#region Fields
        string sCollectionNames="ApplicationDocumentation,Correspondence,"+
            "LeasingDocumentation,LoanDocumentation,ManagementDocumentation,"+
            "PropertyDocumentation,TransactionalDocumentation,UnmatchedDocuments";
        string sCustomContentTypeName = "Debt Asset Content Type";
        #endregion

        #region Feature Activated event
        /// <summary>
        /// This event will get triggered once the fetaure is activated
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            using (var web = properties.Feature.Parent as SPWeb)//To get current web
            {
                string[] sListNames=sCollectionNames.Split(',');//Extract Library name from string variable using "," as delimiter

                foreach(string sListName in sListNames)//Loop through every collection..
                    fnAssociateContentTypeToList(web, sListName, sCustomContentTypeName);
            }
        }
        #endregion

        #region Function is used to associate content type to corresponding list.
        /// <summary>
        /// This function is used to associate content type to corresponding list.
        /// </summary>
        /// <param name="web">The web where the list exists</param>
        /// <param name="sListName">List name to which content type has to be associated</param>
        /// <param name="sContentTypeName">Content type which needs to be associated to collection</param>
        private void fnAssociateContentTypeToList(SPWeb web, string sListName,string sContentTypeName)
        {           
            web.AllowUnsafeUpdates = true;
           
            SPList list = web.Lists.TryGetList(sListName);//Will get the list if it exists, or else will return null.
            if (list != null)//Check if list exists
            {               
                list.ContentTypesEnabled = true;//Enable allow content types.
                if (web.ContentTypes[sContentTypeName] != null)//Check whether corresponding content type exists at respective web
                {
                    SPContentType oContentType = web.ContentTypes[sContentTypeName]; //Get content type using its name                   
                    list.ContentTypes.Add(oContentType);//Add content type to list
                }
                list.Update();//Updat the changes
                fnChangeContentTypeOrder(list, sContentTypeName);//Call this function to change content type ordering
                web.AllowUnsafeUpdates = false;
            }
        }
        #endregion

        #region Function is used to change content type ordering
        /// <summary>
        /// This function is used to change content type ordering
        /// </summary>
        /// <param name="list">List for which ordering has to be implemented</param>
        /// <param name="sContentTypeName">Content type name which has to come first</param>
        private void fnChangeContentTypeOrder(SPList list, string sContentTypeName)
        {
            //Make this the default content type
            IList<SPContentType> ctorder = list.RootFolder.ContentTypeOrder;//Get the content type order for list
            SPContentType[] newCTorder = new SPContentType[1];
            for (int i = 0; i < ctorder.Count; i++)//Loop through associated content types order
            {
                SPContentType ct = ctorder[i];
                if (ct.Name.Equals(sContentTypeName))//Check if the name is matching with param sContentTypeName
                {
                    newCTorder[0] = ct;//Set param sContentTypeName as first and defaul
                }
            }
            // Set the new order and update folder
            list.RootFolder.UniqueContentTypeOrder = newCTorder;
            list.RootFolder.Update();
        }
        #endregion
       
        #region Feature Deactivating event
        /// <summary>
        /// This event will get triggered while deactivating the feature
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            using (var web = properties.Feature.Parent as SPWeb)
            {
                fnRemoveContentTypeFromList(web, sCustomContentTypeName);
            }
        }
        #endregion

        #region Function is used to remove content type association with list
        /// <summary>
        /// This function is used to remove content type association with list
        /// </summary>
        /// <param name="web"></param>
        /// <param name="sContentTypeName"></param>
        private void fnRemoveContentTypeFromList(SPWeb web, string sContentTypeName)
        {
            // Get the obsolete content type.
            SPContentType obsolete = web.ContentTypes[sContentTypeName];
            if (obsolete != null) // We have a content type.
            {
                IList<SPContentTypeUsage> usages = SPContentTypeUsage.GetUsages(obsolete);
                if (usages.Count > 0) // It is in use.
                {
                    //throw new SPException("The content type is in use in the following locations:");
                    foreach (SPContentTypeUsage usage in usages)
                    {
                        if (usage.IsUrlToList)
                        {
                            string[] sUsageUrl=usage.Url.Split('/');
                            SPList oList = web.Lists[sUsageUrl[sUsageUrl.Length - 1]];                         
                            if (oList.BaseType == SPBaseType.DocumentLibrary)
                            {
                                web.AllowUnsafeUpdates = true;
                                if (oList.ContentTypes[sContentTypeName] != null)
                                {                                   
                                    oList.ContentTypes[sContentTypeName].Delete();
                                }
                                oList.Update();
                                web.AllowUnsafeUpdates = false;                               
                            }
                        }
                    }                  
                }
                else // The content type is not in use.
                {                   
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        web.ContentTypes.Delete(obsolete.Id);
                    });
                }
            }
            else // No content type found.
            {
                throw new SPException("The content type does not exist in this site collection.");
            }
        }
        #endregion

Activate Feature:-
Once after this deploy the code and activate feature, the scope of this feature is “Web”.

Testing:-
Navigate to any specified doc library and check for default content type in list settings. It should show custom content type as default one.

Deactivate Feature:-
Deactivate the feature, this should remove custom content type from all associated specified lists.

Testing:-
Navigate to any specified doc library and check for default content type in list settings, it should get revert back to document content type

Note :- When you run this project from visual studio for more than one time, you will face some caching error. it's adviced either to close and reopen visual studio for every run or execute the following command in powershell "stop-process -processname vssphost4 -force", or Go to windows task manager and delete the process named "vssphost4.exe".

No comments:

Post a Comment