Linq to XML and Deleting Lists on Feature Deactivation

Posted Thursday, September 24, 2009 3:04 PM by CoreyRoth

A few months ago, I discussed how to use LINQ to XML to parse your elements.xml file to delete any files that you may have deployed on feature activation.  Today I have decided to reuse this concept to delete any lists that I have created when I deactivate a feature?  Now you may ask, “why would I want to delete a list when a feature is deactivated?  I’ll lose all of my data in that list!”  My answer is: Yes, of course you will, but sometimes when building a feature to deploy a list(s), you want to delete the list each time before you deploy a new version of it.  During development this is a huge time saver.  Right now, I am working on a feature that deploys four document libraries.  This means I have to manually delete each one.  That is a huge waste of time, but what is nice is that we can reuse the concept above with LINQ to XML and delete lists instead. 

The code is quite similar.  Have a look.  We first, write some code to get the path to the elements.xml file.  This code snippet assumes, it is always named Elements.xml.  Maybe in the future, I will have it look in the feature.xml file, get all of the ElementManifest definitions and then delete whatever it finds in each file.  For now though, we assume, you can change the path as needed.

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

{

    using (SPWeb currentSite = (SPWeb)properties.Feature.Parent)

    {

        string elementsPath = string.Format(@"{0}\FEATURES\{1}\Elements.xml", SPUtility.GetGenericSetupPath("Template"), properties.Definition.DisplayName);

        DeleteLists(currentSite, elementsPath);

    }

}

From here, it passes a reference to the current SPWeb and the path to the XML document.  The path to the elements.xml file is used to populate an XDocument which we can then query with LINQ to XML.

private void DeleteLists(SPWeb currentSite, string elementsPath)

{

    try

    {

        XDocument elementsXml = XDocument.Load(elementsPath);

        XNamespace sharePointNamespace = "http://schemas.microsoft.com/sharepoint/";

 

        // get each URL to each list

        var listInstances = from module in elementsXml.Root.Elements(sharePointNamespace + "ListInstance")

                        select new

                        {

                            ListUrl = (module.Attributes("Url").Any()) ? module.Attribute("Url").Value : null,

                        };

 

        // iterate through each list and delete it

        foreach (var listInstance in listInstances)

        {

            try

            {

                SPList currentList = currentSite.GetList(string.Format("{0}/{1}", currentSite.Url, listInstance.ListUrl));

                currentList.Delete();

            }

            catch (System.IO.FileNotFoundException e)

            {

                // this exception is thrown if the list does not exist

            }

        }

 

        // update the site

        currentSite.Update();

    }

    catch

    {

    }

}

This code is quite similar to that used in my other post, however instead of looking for Module elements we are looking for ListInstance elements.  It creates a list of those Urls to each list and iterates through them.  For each list it finds, it deletes the list.   I’ve written code in the past to manually delete lists, I create by name.  That works fine, but the name of each list has to be maintained.  Now, I just attach this to any feature I am working on and it deletes any list (or lists) that I throw at it.  More than likely this isn’t something you want once you go to production, but it will save you a ton of time during development.

Comments

No Comments

Leave a Comment

(required)
(required)
(optional)
(required)