Monday, August 27, 2007

Debugging custom navigation providers in MOSS

Microsoft has done quite a bit to ease pain of navigation in MOSS, but there are plenty of scenarios when you would want to have a custom navigation scheme. I am currently building a custom navigation provider for MOSS 2007, which does not need to depend on the site heirarchy and can go many levels deep if need be. I was having trouble debugging this navigation provider (which was created in Visual Studio 2005 as a class in a class library project).

I created and compiled the dll, strong named it and deployed it to the GAC using gacutil. I also added the entry in the providers section. After some cajoling, the custom navigation started showing up in MOSS (not exactly how I wanted it yet, but doing one thing at a time helps ). Now, of course I wanted to debug it :). This is where I came across interesting scenarios. I removed the dll from the GAC and changed the VS output to go straight to the bin directory of the web application. I then got the expected error 'The assembly does not allow partially trusted callers'. Then I added the AllowPartiallyTrustedCallers attribute to the assembly - and guess what (it still didnt work). I then added a safe controls entry and an assembly entry for my assembly and raised the trust level of the web.config to WSS_Medium and it STILL complained about the same error. At this time I raised the trust level to full and that is when things started working.

I think I know why I had to do this but Ill run it by some MCS folks and see if I am right and then update this. Ill also write up an article explaining the design and architecture of the custom navigation provider soon.

Wednesday, August 22, 2007

Traversing lists in MOSS 2007

As you all might or might not know, WSS 3.0 and MOSS 2007 support folders in lists. This is honestly a really cool feature/enhancement to the list functionality. This opens the door to a lot more possibilities.

However, you need to be a little careful with traversing lists that you create folder heirarchies in. Traversing a list is not as obvious as you think. I was a little surprised that the solution was not intuitive.

Here are some of the caveats that I discovered:
1. A call to list.Items will not bring forth your folders. Instead, it will bring forth ALL the regular items, regardless of the folder heirarchy they live in. So it doesnt matter if an item is at the root level or 4 levels deep - it will show up in the call to list.Items.

2. We have another property available for the folders :). However, a call to list.Folders will bring forth all the folders regardless of their heirarchy in the list.

Keith Ritchie has a solution that works and he has done good homework around this problem. Be sure to have a look at his post here.

Wednesday, August 1, 2007

MOSS 2007 - Enable treeviews on all sites programatically

I just added a MOSS utility (to my growing list of MOSS utilities) that would allow me to enable treeviews on all sites programmatically, rather than going into each site doing it manually. This is significant time savings when you are doing a migration - because there are potentially hundreds of sites that already exist and treeview is not enabled on them.

Here is the code. This assumes that you run a stsadm -o enumsites on the server so that you can get the list of the site collections on your server. This also assumes that you are reading that list from a config file (because you might want to run this for a subset of your site collections).

public static void EnableTreeView() {

Console.WriteLine("Enabling treeviews");

try {

NameValueCollection coll = (NameValueCollection)ConfigurationManager.GetSection("FarmSettings/SiteCollections");

string[] sitecolls = coll.AllKeys;

foreach (string sitecollstr in sitecolls) {

SPSite sitecoll = new SPSite(sitecollstr);

SPWebCollection webcols = sitecoll.AllWebs;

foreach (SPWeb web in webcols) {

Console.WriteLine("Enabling treeview for site: " + web.Url);

web.TreeViewEnabled = true;
web.Update();

web.Dispose();

}

}

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

}


If you have too many sites, you can pipe the output to a file for readibility.

[consoleapp.exe] > C:/treeviewSites.txt




Windows service to publish files programmatically to MOSS 2007

I recently wrote, tested and deployed a .NET 2.0 Windows service to import files into MOSS 2007 sites and document libraries. This service watches a file share (using the FileSystemWatcher class) on another server and moves the file into a MOSS 2007 document library. Here are the salient features:



1. Watches the file share and all folders under that share. Picks up the files as they are created/changed on this share and imports them into MOSS 2007. Deletes the files from the file system after the import. The users are responsible for ensuring that the

2. Accounts for the long copy operations, when the file may not have finished copying when the service goes to pick it up. The way to do that is to open the file in FileShare.None mode and catch the appropriate exception. Wait for a given period of time (few seconds) and retry. Do this the appropriate number of times based on the requirements.

3. Does a clean sweep of the system everytime the service starts to account for the files that it might have missed since the last time it was stopped.

4. Logs the files published/errors to the event log. This helps to track the health of the service - understand what is going right/wrong.



A few things to keep in mind:

1. In the installer class, do not hardcode the password of the account under which the service will run. Do not even read the credentials from a config file. I asked our production environment admins to run the service under a moss service account with enough privileges.

2. Do not do an infinite loop on the number of retries when you cannot get exclusive access to the file. If somebody opens the file and goes home for the day, your service is going to be spinning its wheels trying to get access to that file all night.

3. Review the business case for this requirement. If all that is required is to index these files, you could use MOSS Search to index file shares pretty easily. Also review the business users understand the capabilities of your service, so they dont tax it by creating bogus directories and putting thousands of files in them.



All in all, this service really helps the business because they can automatically import thousands of files into MOSS just by copying them into a file share. I cannot publish the code because the company "owns" that, but hit me up if you need help/advice on how to do this and Ill be glad to guide you.