Friday 19 March 2010

SharePoint 2007 Feature Deployment - Creating Lists with Data Programatically versus Declaratively

To simplify SharePoint deployment, it is a good practice to deploy supporting components such as lists as part of the same feature (so they don't need to be created manually).

While it IS entirely possible to deploy list instances WITH data with a declarative ListInstance block as below (see xml snippet below, and see http://msdn.microsoft.com/en-us/library/ms478860.aspx), the drawback is that you have little control over how the data is actually deployed to your lists. For example, if I deploy the package twice, it will simply double-up on the data - which is not an ideal scenario.

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- NOTE: FeatureId is the feature where the list template is defined, 
  NOT the current featureId. Template Type should match the list template type
  -->
  <!--Create the list instance-->
  <ListInstance FeatureId="a0bf89ed-c424-4391-ba75-0e43d3391bdb" 
                Title="SAPState" Description="SAP State List (Created by a Feature)" 
                Id="1099" TemplateType="100" Url="Lists/SAPState">
    <!--Add the data -->
    <Data>
      <Rows>
        <Row>
          <Field Name="ItemId">NSW</Field>
          <Field Name="Title">New South Wales</Field>
          <Field Name="DisplayOrder" />
        </Row>
        <Row>
          <Field Name="ItemId">ACT</Field>
          <Field Name="Title">ACT</Field>
          <Field Name="DisplayOrder" />
        </Row>
        <Row>
          <Field Name="ItemId">VIC</Field>
          <Field Name="Title">Victoria</Field>
          <Field Name="DisplayOrder" />
        </Row>
      </Rows>
    </Data>
  </ListInstance>
</Elements>

To work around this issue, I recommend that you make use of a SPFeatureReceiver and use code to programatically control the creation of your lists and list data. See the helper method below for an example. Note that you retrieve the list template you want to use via the SPWeb.ListTemplates[] collection

/// 
        /// Creates custom list using the specified template and adds lookup data as neccessary
        /// 
        /// /// /// /// /// /// 
        public static Guid ProvisionCustomList(SPWeb web, string listName, string listDecription, SPListTemplate listTemplate, List listData)
        {
            SPList tryList = null;
            Guid listID = Guid.Empty;
            try
            {
                tryList = web.GetList(listName);
            }
            catch
            { }

            if (tryList == null)
            {
                try
                {
                    listID = web.Lists.Add(listName, listDecription, listTemplate);
                }
                catch (Exception ex)
                {
                    throw new Exception("Cannot instantiate the list '" + listName + "'. " + ex.Message, ex);
                }

                if (listID != Guid.Empty && listData != null && listData.Count > 0)
                {
                    web.AllowUnsafeUpdates = true;
                    var list = web.Lists[listID];
                    try
                    {
                        foreach (var dataRow in listData)
                        {
                            var listItem = list.Items.Add();
                            listItem["ItemId"] = dataRow.ItemId ?? "";
                            listItem["Title"] = dataRow.Title ?? "";
                            listItem["DisplayOrder"] = dataRow.DisplayOrder ?? "";
                            listItem.Update();
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Cannot add the data to the list '" + listName + "'. " + ex.Message, ex);
                    }
                }
            }

            return listID; 
        }

1 comment:

Vamshi Govind said...
This comment has been removed by the author.