Skip to main content

How to create List Templates and List Instances with VSeWSS 1.3


The task of every Sharepoint developer is to provide a solution that is easy to be deployed to the end systems of the client being it development, staging or production environment. In most of the cases a real life SharePoint project has a set of custom lists, document libraries and custom pages/web parts, so covering them will make the every day life of most of you a little bit easier. In this article I will cover the approach that I found most useful for myself from a developer stand point of view.

Once the VSeWSS 1.3 is being installed on the machine where Visual Studio .NET is located we get access to the Sharepoint project templates:

One of the available Sharepoint templates is the List Definition which is the one we can use to create a Sharepoint list. After selecting it we will have the chance to select what kind of template we want to create:

In our case we want to create a custom list, so we just have to select the Custom List base definition. However this is just a definition and what actually we want to do is to have a list instance based on that definition. We want to create the instance of the list automatically when we are deploying our application and not doing it manually. This can be done by just checking the Create an instance of this list option which will include one more file called instance.xml. This is how the list definition project looks like:

The files that we are interested in are the schema.xml, Instance.xml and ListDefinition.xml where the schema.xml is the most important one since it contains the definition of the list: fields, content types, views and forms and is the one that will be modified the most, while the other 2 files once created usually don't require any modifications. This is how the different files look like:
ListDefinition.xml

Instance.xml

Schema.xml

Note: It is critical to have the Id attributes of the ListDefinition.xml and the Schema.xml and the FeatureId one in the Instance.xml synchronized all the time since they are used by Sharepoint to connect the different pieces together and if the mentioned identifiers are different usually this means troubles ones the feature is deployed to Sharepoint. Usually the result is either missing list instance or the list display form page shows you nothing but a standard browser message for missing page and you can not view the items in the list.


If we take a closer look at the Schema.xml we can see that actually our custom list has the Item content type as base one and that there are currently no fields defined, which is what we would expect for an empty list template. From this point on our task is to modify the list template in order to achieve our goal and we can do it the hard way or the easy way:
Modify the schema.xml by hand. This includes creating the fields and content type definitions. I'm sure that there are people out there that are willing and are using this approach, but personally except for learning purposes I would never do that again since too many things can go wrong and it is just waste of time, although it is very helpful to know what is happening behind the scenes in order to troubleshoot the eventual problems that can occur and WILL occur later. This approach may work for a list or two but generally we have much more than that.
Create the list using the SharePoint UI and export it using the SharePoint Solution Generator 2008 which comes with the VSeWSS 1.3. This approach allows us to create all we need using the SharePoint UI and later export it as Visual Studio .NET projects that have exactly the same structure as the one that was created using the Visual Studio .NET SharePoint template.
Without any doubt I would choose the second approach since it saves a lot of development time. Unfortunately it is not automating 100% of the work that needs to be done, but this is mostly related to the content types of the list. Even if we define a content type using the SharePoint UI that later is being used by the list in the result Visual Studio .NET project this content type is only included as embedded one in the schema.xml and when it is deployed to a different SharePoint there is no way to see it except from the list settings and thus there is no way to reuse it in different lists or use it as base of another content types. Of course since it is embedded in the schema.xml with the help of a console application that goes through the solution folder and searches for the schema.xml files and the Visual Studio .NET pre-build events we can easily automate the extraction of the content type in a separate xml that is being added to the project when we are re-building it and later being deployed as a separate content type feature automatically without the need to do anything extra, which is the ultimate goal of every developer. Of course probably there is a reason that this is currently not supported in the solution generator itself but writing such tool that covers 80% of the cases is not that difficult.


Here is what you need to do to export your lists/documents libraries using the solution generator:
Open the SharePoint Solution Generator 2008 and select List Definition

After you specify the url of the SharePoint site you will have the option to select a subset of all the site lists that exists on that site. In our case we just need the MyCustomList one.

The last step of the process is to specify the name of the project and the location where the solution generator should create the Visual Studio .NET project.
Usually as in every real life project the lists will need to be modified - add or remove a field, etc. Once we have the project with the lists created this is an easy task. The modification can be done using the SharePoint UI and exported the same way. In most of the cases I usually modify the ListDefinition.xml and the Instance.xml files in order to change the titles and the descriptions of the lists and I don't want these files to be overwritten, so I generate the new definition in a temporary folder and just copy the Schema.xml in the real project, since it is the one that contains the list modifications. As I mentioned earlier you need to be careful here since during the new export the Id attribute of the List element in the Schema.xml file is being changed, so you need to propagate it to the Instance.xml and the ListDefinition.xml files.

Once we have the Visual Studio .NET project ready we can deploy the lists to different sites quite easily:

Note: Deploying to a site that still doesn't have existing list instances of the list templates is straightforward and will hardly ever cause a problem. However this is not the case if we just modified the list templates and are trying to re-deploy it to a site where it was deployed previously and we have already existing list instances created using the list templates. The chance that you will get the following message is pretty big: Feature {Guid} for list template '100' is not installed in this farm. The operation could not be completed. I've found this problem the painful way and after some analyses actually the reason for the error is pretty obvious. The resolution of this problem will be covered in Fixing 'Feature {Guid} for list template is not installed in this farm. The operation could not be completed' , where I will explain the exact reason and will show I handy tool I've developed that can automatically fix the problem for you.

Fixing 'Feature {Guid} for list template is not installed in this farm. The operation could not be completed'


"Feature {Guid} for list template is not installed in this farm. The operation could not be completed." Probably this is the message that I get the most when I'm developing a project that has a high usage of list created from list templates. You can find useful one of my previous articles on that topic - How to create List Templates and List Instances with VSeWSS 1.3

Here is a screenshot of a message that that I got recently and it happened just after I deployed a SharePoint solution using the VSeWSS 1.3 that had couple of content types, list templates and list instances.

Although the message is about a list template not being installed you can pretty quickly guess that the problem is the list instance that is using the list template since actually the message was shown when you tried to open the list itself. My first reaction was to check the SharePoint FEATURES folder (%Program Files%\Microsoft Shared\Web Server Extensions\12\Features ) for a feature with that Guid and as I expected I couldn't find anything there that matches the identifier from the error message. The hardest part is to find a starting point for the troubleshooting which can give us some directions to what to look for and in this case since the problem is in the list instance the most obvious thing is to actually see what kind of properties SharePoint has for this particular list and is there a one that has something to do with the Guid.

Using one of my favorite tools (SharePoint Manager 2007) that helps me a lot during the troubleshooting of all the problems I face during my SharePoint development it is pretty easy to quickly check all the properties that a list has. Luckily enough for me I found what I was looking for and right away had the idea what is wrong and what is causing the error. The field that contained the Guid from the error message was a value of the TemplateFeatureId list property. So here is a quick explanation of what actually happened:


During the deployment of a feature using the VSeWSS 1.3 the old one is being retracted and thus the feature files are being removed from the 12 Hive folder of SharePoint and meanwhile a new Guid is being generated by SharePoint internally which is then being used instead of the fake one in the schema.xml, listdefinition.xml and instance.xml files in your Visual Studio .NET project. Even when you open the instance.xml file you can see a message there saying the following:
The following Guid for FeatureId is used as a reference to the list definition, and it will be automatically replaced with actual feature id at deployment time.
So now we have the TemplateFeatureId of the list instance the same as the list template one. During a new deployment of the list template if there is already an existing list instance it is being preserved and no new one is being created, which is pretty much expected since we don't want to loose our already existing list with all its data just because we redeployed the list template. So what happens is that the list template feature that the list instance is pointing to is being replaced by the new one which has a new FeatureId generated by SharePoint, but the TemplateFeatureId of all the list instances that are instantiated from the list templates remain the same and thus when the list is being opened no such list template is being found and the exception thrown by SharePoint finally makes sense.

From the problem description above the solution seems to be pretty easy. We just need to change the TemplateFeatureId to the Guid of the newly deployed list template. The problem here is how do we map the old list template to the new one that was deployed. Of course for a man this is easy since we can quickly find the folder of the feature, take a look at the new Guid in the feature.xml and then change the TemplateFeatureId of the list, but we don't want to do that every single time we deploy our solution to SharePoint which can be pretty often during the development phase. The question here is can we automate this process, so the problem can be fixed just by clicking a button? The answer is Yes, we can automate the process and make it work in most of the cases. I've created a pretty convenient tool called List Instances Fix Tool that you can download from www.myitechnology.com

When you run it on the SharePoint server it will give you a list with all the Web Applications and their site collections that exist in the SharePoint Farm. You can easily see if there are bad list instances in a site by expanding the site collection. The tool will give you the total number of lists in this site and the count of the bad ones along with an exclamation icon if there is at least one bad one. Once you click on the site a list with all the bad list instances will be presented. The tool will try to guess which is the right list template, but if it can not do that you still have the option to select it manually from all the available list templates - activated or not.

Comments