Search This Blog

Monday, April 4, 2011

Deleting content type with all references from a site collection : SharePoint 2010

Quite often we come across a requirement where in we need to delete a content type from a site collection that is no longer being used.However, the problem that we usually face us that if the content type is being used in any lists, documents, inherited content types across the site, we are not able to delete it as sharepoint gives the error - "The content type is still in use".

Therefore, in order to delete the content type completely from a site collection, we need to first delete all the documents/list items using the content type, any list content types association as well as any content types inherited from it.

The code given below does all this stuff using the 'SPContentTypeUsage' collection.

I have developed a console application to achieve this.The same code can also be used in a webpart/user control/timer job :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.IO;
using System.Xml;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SPSite site = new SPSite("http://my-sp-site");

            SPWeb web = site.OpenWeb();

            string strContentTypeName = "CT29Mar7";

            try
            {
                 SPContentType cType = web.ContentTypes[strContentTypeName];

                 DeleteContentType(cType.Id, web);
   

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadLine();
            }


          
            Console.WriteLine("Content type deleted from the site collection.!!");
            Console.ReadLine();
           
        }



private static void DeleteContentType(SPContentTypeId objSPContentTypeId,SPWeb web)
        {

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {

                // Get the obsolete content type.
                SPContentType contentTypeToDelete = web.ContentTypes[objSPContentTypeId];

                if (contentTypeToDelete != null) // We have a content type.
                {
                    IList<SPContentTypeUsage> usages = SPContentTypeUsage.GetUsages(contentTypeToDelete);

                    if (usages.Count > 0) // It is in use.
                    {
                        //iterating through usages
                        foreach (SPContentTypeUsage usage in usages)
                        {

                            string currentWebUrl = web.Site.Url + usage.Url;

                            using (SPSite site = new SPSite(currentWebUrl))
                            {
                                using (SPWeb currentWeb = site.OpenWeb())
                                {
                                    currentWeb.AllowUnsafeUpdates = true;

                                    //if usage is for a list
                                    if (usage.IsUrlToList)
                                    {
                                        SPFolder listFolder = currentWeb.GetFolder(usage.Url);
                                        SPList list = currentWeb.Lists[listFolder.ParentListId];

                                        foreach (SPListItem item in list.Items)
                                        {
                                            if (item.ContentTypeId.Equals(usage.Id))
                                            {
                                                item.Delete();

                                            }

                                        }

                                        list.ContentTypes.Delete(usage.Id);
                                    }
                                    else //usage is for a content type inherited from the content type being deleted
                                    {
                                        SPContentType cType = currentWeb.ContentTypes[usage.Id];

                                        if (cType != null)
                                        {
                                            //calling the method recursively to delete all content types inherited from this content type as well
                                            DeleteContentType(cType.Id, currentWeb);
                                        }

                                    }
                                }
                            }


                        }


                    }

                    usages = SPContentTypeUsage.GetUsages(contentTypeToDelete);

                    if (usages.Count == 0)
                    {
                        web.ContentTypes.Delete(contentTypeToDelete.Id);
                    }

                }

            });
           
           

        }



    }
}




No comments:

Post a Comment