Change the welcome page of your SharePoint 2007 site programmatically

Today I was trying to figure out how to change the welcome page of a SharePoint 2007 site programmatically. I couldn’t really find useful links on Google, so I figured I’d go and play around a bit with the object model.

Apparently the PublishingWeb object has a property called DefaultPage, which takes an SPFile object as a value. I ended up with the following code to change the welcome page:

using(SPSite siteCollection = new SPSite("http://yourserver"))
{
SPWeb targetWeb = siteCollection.AllWebs["YourWebName"];
SPFile newWelcomePage = null; // Change the code here to set the SPFile object to your new welcome page

if(PublishingWeb.IsPublishingWeb(targetWeb))
{
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(targetWeb);
publishingWeb.DefaultPage = newWelcomePage; // this sets the new welcome page
publishingWeb.Update();
}
}

That should do the trick :). I hope this post is useful for anyone who’s also trying to achieve the same thing!

Can’t find that newly saved list template when creating a new list?

Ever came across that situation where you just saved an existing list as a template? And then you tried creating a new list based on that template? No matter how hard you looked, you just couldn’t find the template saved earlier when trying to create a new list?

Chances are that your list was provisioned using a feature and that the Hidden property of the <ListTemplate> element was set to True. That property prevents the list template from showing up on the page where you create a new list. Unfortunately, this also makes it a little bit more difficult to create that list through the SharePoint user interface.

Yes, I said a little more difficult, not impossible. There happens to be a work-around that allows you to still perform that action through the UI. This little trick was inspired on something that worked in SharePoint Portal Server 2003 as well. Sometimes the UI doesn’t allow you to perform a certain action (for example, it hides the action). However, the page that performs the actual action, could be fooled in performing the hidden action, by passing the correct query string parameters.

In this case, we will do exactly the same thing to create our list. Navigate to the site where you want to create your list and go to View All Site Content. On that page, click the Create button. As you already found out, the template you just saved isn’t here. Now, click the link to create a new Custom List.

Notice the address bar in your browser. The new.aspx page takes a FeatureId and ListTemplate as a parameter. The FeatureId parameter matches with the feature which installed this list on the SharePoint environment. The ListTemplate parameter probably speaks for itself; it specifies the template ID of the list.

To create a list based on a saved template, you need to specify an additional parameter to new.aspx. This parameter is called NewPageFilename and its value should be the name of your STP file.

Now you should look up the feature that installed the list you’re trying to create and copy its ID. Take this value and replace the value for FeatureId in the query string. Also, look up the <ListTemplate> element that is defined in the feature and copy its Type attribute. This value corresponds with the ListTemplate parameter in the URL, so replace the value in the query string with the value you just copied.

When you’re done, your URL should look something like this (without the square brackets):

/_layouts/new.aspx?NewPageFilename=[YourTemplateName]%2Estp&FeatureId={735DE88F-B6C1-4571-8D5F-08BF22D6CF40}&ListTemplate=130185

There you go! This URL should allow you to create your list. Navigate to the URL above and fill out the form like you normally do and you’re done :) This trick probably also works with hidden lists that don’t have a saved template. In that case, just omit the NewPageFilename parameter.

SharePoint hotfix 939077 partially breaks Advanced Search

Microsoft released a hotfix package for SharePoint Server 2007 and for SharePoint Server 2007 for Search. This hotfix package fixes an issue where sites that use forms-based or cookie-based authentication are not being crawled in SharePoint. It also fixes an issue where slow performance of the BLOB cache is experienced. The latter is the reason why we installed this hotfix on the production environment of a client I’m currently working at.

The hotfix addresses the issues just fine. However, on our environment it appears to be introducing a new issue: It breaks the out of the box SharePoint Advanced Search Box web part with the following dreaded error: “Object reference not set to an instance of an object.” 

This is all the information you’re getting, no stack trace, nothing in the logs. This pretty much left me clueless. At first I thought I screwed something up with my own search settings. That feeling got stronger after I created a default Search Center site: the Advanced Search web part was still working there.

After some puzzling I concluded that it had to be a difference in the web part properties, since it appeared to be working on the default Search Center site. So I exported both web parts, and examined the differences…and indeed, the only differences where property settings.

Right, back to my non-working version of the web part. In my version I was hiding the Properties section which is visible in the default web part. After making it visible on my web part again, it worked! So much for testing your hotfixes before rolling them out…

The problem is definitely the hotfix. I also installed it on my development environment and it broke the Advanced Search web part as well…

The hotfix cannot be uninstalled, so now we’re pretty much waiting for the hotfix-hotfix from Microsoft. For now, I guess I’ll just have to remove the Advanced Search web part from the search results page.

SPWeb.AvailableContentTypes or SPWeb.ContentTypes?

There are two ways to get a collection of content types for a web site. One is the SPWeb.AvailableContentTypes collection and the other one is the SPWeb.ContentTypes collection. Right, what’s the difference then, I hear you say. A quote from the MSDN documentation:

Gets the collection of all content type templates for the current scope, including those of the current Web site, as well as of any parent sites.

Use the ContentTypes property to return only the content types of the current Web site.

The documentation is not very extensive here. The difference really is a bit vague. For you programmers out there it is good to realize that an important difference between the two exists. The AvailableContentTypes collection is read-only!

Allow me to ellaborate a bit more on that. A while ago I tried to programmatically add an information management policy to a content type (I’ll write something on that later). So, I retrieved the content type like this:

SPWeb web = SPContext.Current.Web;
SPContentType contentType = web.AvailableContentTypes[new SPContentTypeId(myContentTypeId)];

When trying to add the policy to the content type, I just kept getting an error: “The collection cannot be modified”. This seemed very strange to me, and I couldn’t figure it out at first. Google and MSDN both were not very helpful in trying to find out what went wrong.

The stack trace informed me that the error occurred when the SPContentType.Update() method was called. So I started up Reflector (this really is a must-have tool for working with MOSS 2007, sad but true) to see what was happening in that method. After a while I found out that when you access the AvailableContentTypes property, a read-only collection of SPContentType objects is returned. Everything worked fine when I used the SPWeb.ContentTypes collection.

Right, that pretty much made me feel like banging my head against the wall. I spent a couple of hours trying to figure out why it wouldn’t work and it turns out to be so easy. Those are the moments when you wish that the MSDN documentation would contain more information than just a basic description of a property.

Of course, thinking about it, it probably makes sense that the AvailableContentTypes property is read-only. After all, it does return content types that belong to the parent site and you probably won’t want to go around editing those directly from a child site. Oh well, let us just be grateful that Reflector exists.

For all of those who have been living in a cave lately, here is a link to the site where Reflector can be downloaded:

http://www.aisto.com/roeder/dotnet/

Hello world!

Hm, being a programmer myself, I probably should leave the title like this. Well, first of all: welcome to my blog. I figured I should write a little bit more about the work I do currently. Events that have occurred in the last couple of weeks reminded myself that I should document what I’m doing.

 So, the goals of this blog are:

- Writing about Microsoft Office SharePoint Server 2007 (in short: MOSS 2007);
- Share my knowledge with anyone who is interested;
- Keep an archive for myself of anything that I encounter during work;