Why do I see two copies of my Custom List Instance in a SharePoint Site?


Introduction

 

Over my years in SharePoint development I have had the following issue occur.a couple of times.

Actually back in July 2010, I posted a blog entry which solved a problem with the Manage Content and Structure page which was related to duplicate lists in a site.

  • I create a custom List with a customised List Definition which uses a schema.xml to define the List Template
  • I create a Feature which uses the customised List Definition to create a new List Template with the <ListTemplate> feature element.
  • I configure the feature to create an Instance of the list using the <ListInstance> feature Xml element,
  • Activate the feature in a SharePoint Web, click Site Actions->View All Site Content.
  • Two instances of the list appear in the View All Content page, both reference the same SharePoint list.
    Figure below shows an example of two duplicate lists in the web.
    duplicatelistitemsinweb

 

I have then always wondered what causes this?

What is interesting is that one link points to one view and the other link points to a different view, this hint was the lead to help solve the issue.

 

Solution

 

I started the investigation by digging into the SharePoint databases now quick warning, “you should not read or edit the database, doing so will leave your SharePoint installation unsupported by Microsoft!”

However, I was very careful and did not make any changes to the database.

It was one of the tables that lead me to working out why I was having these duplicate links. This table was the BuildDependencies table. I performed a

SELECT TOP 1000 [SiteId]
      ,[DirName]
      ,[LeafName]
      ,[TargetDirName]
      ,[TargetLeafName]
      ,[DirectDependency]
      ,[DeleteTransactionId]
  FROM [BuildDependencies]
  Where [DirName] LIKE ‘sites/sitename%’

Looking through the results I could see that the list had two views one called ‘ByFeatures.asppx and the other ‘AllItems.aspx’

This was correct my List Schema had defined these two views and then it dawned on me, what if SharePoint is looking at the schema.xml to work out which list page to display in the View All Content page.

So I went into my schema.xml and low and behold there was an attribute on the <View> element called DefaultView. Now both the AllItems.aspx and ByFeatures.aspx had this set to TRUE.

listschema-defaultview

 

Eureka!

So to fix this I followed this process:-

  • Updated the schema.xml <View/> element for the AllItems.aspx view
  • Modified the DefaultView attribute and set it to FALSE
  • Redeployed the solution
  • Perform an IISRESET
  • Deactivate the Feature
  • Delete the list
  • Activate the Feature to create the list

Now I only see one instance of the list in the View All Content page.

However, there is a problem with this approach and that is you lose the data in the list!

 

To Fix Existing Lists with No data loss

So we need a way to fix the lists that have already been created, seeing as the existing lists are not fixed by the schema changes then these properties must have been copied into the content database.

So to fix existing lists do the following:-

  • Browse to the list and open up the List Settings page using the Ribbon
  • Create a new View call it what you want, make sure you set it to default
  • This will reset the Default View attribute on the other views and make the new view the default view.
  • Modify the view that should really be the default view and tick the make default view checkbox. (This doesnt appear if you have multiple views with the default view set).
  • Update the view
  • Delete any views that are not needed

You should now see only one list instance in the View All Site Content page!

Creating List Instance: Object Reference not set to an instance of an object


Introduction

This one is a bit of an old issue but some of my posts are just to remind me of a time that I got stuck in the past. Also if it helps someone else then great.

It is possible to create a feature which creates an instance of a SharePoint List when its activated. However, sometimes you only want a list to be created on the Root Web of a site collection.

Issue

Well the XML for specifying a ListInstance as a feature has an attribute called RootWebOnly which I thought I could use to only allow the ListInstance to be created on the RootWeb.

Unfortunately when you do that you get a message like the following in your SharePoint ULS Logs when the feature is activated:-

Feature Activation: Threw an exception, attempting to roll back. Feature ‘FeatureName’(ID: ‘xxxxxxxx-xxxx-xxxx-xxxxxxxx). Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.SharePoint.SPListInstanceElement.ElementActivated(SPFeaturePropertyCollection props, SPSqlCommand sqlcmdAppendOnly, SPWebApplication webApp, SPSite site, SPWeb web, Boolean fForce)
at Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionListInstances(SPFeaturePropertyCollection props, SPSite site, SPWeb web, Boolean fForce)
at Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionElements(SPFeaturePropertyCollection props, SPWebApplication webapp, SPSite site, SPWeb web, Boolean fForce)
at Microsoft.SharePoint.SPFeature.ProvisionElements(SPFeaturePropertyCollection props, SPWebApplication webapp, SPSite site, SPWeb web, Boolean fForce)
at Microsoft.SharePoint.SPFeature.Activate(SPSite siteParent, SPWeb webParent, SPFeaturePropertyCollection props, Boolean fForce)

The offending Feature ListInstance element is below:-

 1: <?xmlversion="1.0" encoding="utf-8"?>
 2: <Elements
 3: xmlns="http://schemas.microsoft.com/sharepoint/">
 4: <ListInstance
 5: Id="AListId"
 6: Title="A List"
 7: Description="A List 
 8: Description”
 9: Url="Lists/ListUrlHere"
 10: OnQuickLaunch="FALSE"
 11: RootWebOnly=”TRUE”
 12: FeatureId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
 13: TemplateType="45100"></ListInstance>
 14: </Elements>

Solution

To fix the feature activation remove the RootWebOnly=”TRUE” from your ListInstance element manifest file and instead move the RootWebOnly=”TRUE” into your List’s schema.xml.

To ensure that the list is only provisioned at the root web of the site collection change the Feature.xml to use Scope=”Site”

Update:

Thanks to Dennis who picked up my mistake in this post which stated that the RootWebOnly attribute should be moved to the feature.xml.