Friday, 2 March 2007

Creating lists with VSeWSS

This is the first article in a series aimed at explaining the process of creating a MOSS site using SharePoint features. For the full series contents, see my introduction.

Here, we'll look at creating SharePoint lists. For something so simple and core to SharePoint, they're surprisingly difficult to create as a feature. Fortunately Visual Studio extensions for WSS simplifies the process dramatically. If you've not come across this yet I'd recommend trying it - WseWSS is basically a huge help for some SharePoint development scenarios. The following articles are good background:-

Briefly, the process of creating a list in VSeWSS is as follows:

  1. Create a blank Visual Studio project. N.B. if you're actually creating a SharePoint site definition, you should select 'Team Site Definition' or 'Blank Site Definition', as WSeWSS will set you up with provisioning code which will execute whenever a site gets created from this definition.

  2. Select 'Add New Item' on the Project menu, then select 'List Definition' from the SharePoint section.

  3. Typically you should select 'Custom list' as the base list definition from the dropdown. Only select another choice if you're actually extending that list type and want to retain the original's columns. Assuming you want to create the actual list in addition to a list template (more on this later), check the 'Create an instance of this list' box. Note also the option to 'Add with event receiver' - this sets up code which which can be used to handle events on the list, for example when list items are added/edited/deleted.



  4. After clicking OK in the dialog, name your list appropriately. My recommendation would be to avoid spaces or other characters which might get encoded somewhere - the list will have a display name which you can be freer with.

    WSeWSS has now created several files in your VS project.




    We can see the following:-


    • some aspx files, the pages users will use to work with your list. Note these can be customised if you want to deviate from the standard behaviour.

    • instance.xml - this is the file to edit to add initial data to your list. Since this file is automatically linked to the appropriate schema, it's fairly straightforward to edit as VS will tell you the valid nodes as you type (shown below).

    • two .cs files containing method stubs for event handlers. These are ready for you to your implementation to.

    • schema.xml - this contains the CAML which dictates which content types the list stores, any custom views and also has references to the .aspx files we mentioned
  5. If you want to add default items to your list (and you probably do if you created an instance of it), you can edit the instance.xml file. This is made simple because VSeWSS has hooked up instance.xml to the appropriate XML schema (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML\wss.xsd), and you can then take advantage of VS's Intellisense which is inferred from the schema as you type:-



  6. After making any customisations such as editing instance.xml to add list items, go to the properties of your VS project and examine the 'SharePoint Solution' tab. Here you'll see VSeWSS has generated two features for each list. One is for the list instance, the other is for the list template. This can be used by users to create new lists on the site, using the columns you've defined.

  7. Go to the 'Debug' tab on the project properties, and enter the URL of your SharePoint development site. The solution will be deployed to this URL so it's important this value is entered.

  8. Hit F5 and WSeWSS will create and deploy the solution. Note that the .wsp file gets generated in the bin\Debug or bin\Release directory of your project. Keep an eye on the VS status bar in the bottom left to monitor progress. If the deploy succeeded, your list should now be visible in the site specified on the 'Debug' tab.


To anyone who has created SharePoint solutions/features by hand, VSeWSS offers a compelling alternative. No messing around with ddf files and makecab.exe, just hit F5. However, there are a couple of irritations:-

  • Since VSeWSS rewrites the feature.xml file on each deploy, there's no way to customise this file to add something which can't be entered on the 'SharePoint Solutions' area of the project properties. The major example is a feature receiver class to specify code which should run when the feature is activated/deactivated, should you want to do something here. Of course, you could edit the file at the end of the development cycle, but you know damn well there's always further tweaks and re-pasting the XML into feature.xml gets tiresome.

  • VSeWSS recreates the feature GUIDs on each deployment. This is great for development, but means you cannot have other features with feature dependencies on your list features. This can be a pain if you're trying to create a feature hierarchy or rationalise your features so that activating one will activate all required features for a given part of your solution.

Nevertheless, you now have your solution with a feature for each list you added. Well actually you have 2 features for each list you added. Why? Because one is for the list instance and the other is for the list template. Note that you can deactivate the feature for the list template if you don't want your users to be able to create lists from this one.


Next in the series - how to create site columns (fields) which get their data from lists.

15 comments:

Anonymous said...

The information you provided was very useful. However, when you uninstall the feature, I've noticed that the lists still remain in the site and when you click on the list, an error shows up. When you reinstall and reactivate the feature, the list then contains duplicates. I'm assuming that the lists never get fully deleted because it still shows up under the site. How can you ensure that the lists are completely deleted when the feature is uninstalled?

Thanks!

Chris O'Brien said...

Good question. It seems to me that when there is the chance of data loss, deactivating the feature will not remove the site artifact. So anything like lists, site columns which are in use, page layouts/master pages etc. will not be deleted.

If you're absolutely sure the list can be deleted (regardless of any data which has been added), you should be able to use a feature receiver to specify the code which executes at feature deactivation. You could then use the object model to find and delete the list.

Of course, this then means that creating the lists is more involved, and if you're using VSeWSS, you have to add the feature receiver attributes to your feature.xml file at the end of the development cycle and build the .wsp file yourself (since VSeWSS overwrites the file on each deploy).

As far as I'm aware, this would be the only way.

HTH,

Chris.

Anonymous said...

Another comment from me!!(Laurent)
Can you tell us something about the ability to use resource file with the feature instead of hardcoding the values, in order to have multi-L for example!
Do you know things about that?

Many thanks
Laurent

Chris O'Brien said...

Well I guess it's just standard .Net 2.0 localization at the end of the day. The interesting thing is that when SharePoint processes CAML, it understands that if it comes across a token in a specific format, it should look up the string from a resources file.

I can't really give guidance on the specifics, but you can cross-reference instances of MS CAML (e.g. in the Features folder) which use resource strings with the actual values in the resource files/assemblies (using reflector). This should enable you to find the token format to use for you to create your own resources assembly.

boy said...

Hi Chris

I want to deploy 7 list based on custom list and also create instance of each.

What is the best way of achieving this?

Do I need to create a new project for each list?

Thanks for your help.

Amit

Chris O'Brien said...

Amit,

No, you don't need a separate project for each list. If you are using VSeWSS, you can simply do 'Add New Item' in your VS project, and then select 'List Definition' for each of your 7 lists. You should check the box which specifies you also want to create a list instance.

VSeWSS will then add all the necessary files to your project under a folder, so everything related to the list will be in here.

Hope this helps,

Chris.

Anonymous said...

When creating a ListInstance, where the list has a PeoplePicker field, what is the correct format for the data. I have tried the username, email address, and a whole host of other formats. Any help would be greatly appreciated.

MDF

bittercoder said...

Hi Chris, I've been just getting into WSS 3.0 development the last couple of weeks, and decided to start with the somewhat "easier" VseWSS 1.0 route, before getting my hands really dirty with all that feature.xml stuff ;o)

I've got a custom list, and I've customised the NewForm.aspx / EditForm.aspx pages, declaratively adding a web part to the main zone on each page which I had hoped would replace the ListForm web part which is placed there by default - but instead when I deploy both parts are displayed, what's the right way to go about replacing the ListForm web part entirely for a New/Edit list form page?

Chris O'Brien said...

Hi,

What's probably happening here is that the 2 web parts are being added in different ways - one has been added directly to the page (i.e. when you customized it), but the other is being added in the XML definition for the Feature.

In case you haven't come across this yet, it's possible to add web parts to zones by using the 'AllUsersWebPart' tag in the Feature's elements file. This is the preferred way to add default web parts to a page (i.e. so they are present as soon as the page is created) - I'd recommend not customizing the page in SPD and using this tag to include your custom web part instead of the standard ListForm.

HTH,

Chris.

Chris O'Brien said...

@MDF,

Apologies for the delay in replying, I've been on holiday.

That's a good question, I'm afraid I don't know the answer having never needed to use a person/group column in this way. Did you find the answer?

Chris.

butlerTRONIC said...

Hi Chris
Thanks for taking the time to write this up.
I'm using VSeWSS to create a custom list at the moment. The problem I have is that, once deployed to my site, the new fields I have added to the list show up in AllItems.aspx and in the list settings, but they do not show up in NewForm.aspx when you try to add a new item to the list.
Am I missing something fundamental here?

Thanks

Tim

Chris O'Brien said...

@Tim,

Hmm, I've not seen this behaviour I'm afraid. I wonder though, if you've perhaps opened NewForm.aspx in SharePoint Designer at some point in the process perhaps? I'm not 100% sure on this, but it's possible that if the file is customized (see my ghosting/unghosting post) it might not read the current list schema to generate the form. That said, I would have expected that the form is generated by a control so customizing the file would not have this effect.

What happens if you add a new list to your project with VSeWSS and redeploy?

Cheers,

Chris.

butlerTRONIC said...

Thanks Chris
I created another list and added the following to it (*** = my additions, angle brackets removed to post here):

Fields
***Field ShowInNewForm="TRUE" Id="{{A973951A-A379-4405-9AF8-EFAE1690E5D9}}" Name="NewLocation" ***DisplayName="New Location" Required="TRUE" Type="Text"
***/Field
/Fields


ViewFields
FieldRef Name="LinkTitleNoMenu"
/FieldRef
***FieldRef Name="NewLocation"/FieldRef
/ViewFields

Toolbar Type="Standard"/
ViewFields
FieldRef Name="Attachments"
/FieldRef
FieldRef Name="LinkTitle"
/FieldRef
*** FieldRef Name="NewLocation"/FieldRef
/ViewFields

Same result as before – I notice the “New Location” fields doesn’t appear in allitems.aspx until I add it to the second view.

I suspect the problem might be connected to not creating a custom content type to hold the new field, I’ll start again creating the content type first and see where that gets me.
T

butlerTRONIC said...

Still no joy – I just tried creating all of the files by hand rather than using VSeWSS I also used a field from Features\Fields instead of creating one of my own. Same result as before, the feature installs with no errors but when I create an instance of it on the site only the Title fields shows up on the create form.
I’m basing my schema.xml on a copy of the one in Features\CustomList and making the following changes:
1. In Content type, change the Folder TargetName to that of my custom list
2. In Fields, add the full field definition from Features\Fields for the field I want to add
3. In both ViewFields sectors add my extra field
Am I missing out some vital extra stage?
As far as I can tell the features.xml file, manifest etc are all fine and I get no errors on deployment or when I make an instance of the list, add to it etc.

Any suggestions welcome – this is driving me nuts!

Thanks

Tim

Chris O'Brien said...

Hi Tim,

Sorry for the late reply. Hmm, I'm not sure what could be going wrong, but I've not yet needed to modify the schema of a list I'm deploying as a Feature. It seems to me that if there are no errors when the list is created or when items are added, the schema definitions should be OK. One thing though - I notice you have double curly braces in the field ID value - this should only be a single brace.

Otherwise I guess I'd suggest coming at it from a different angle: quickly create a test list using the UI, then examine the CAML behind it using a tool such as Stramit's CAML Viewer. You'll then be able to compare what you've generated with what SharePoint generates.

HTH,

Chris.