Sharepoint Best Practice

The recommended practice for adding items to a sharepoint site is to use features.
One useful technique is to create a feature with an activation receiver.
When you install and activate this you can do whatever you like to the site in code.

The problem is keeping track of what you have done (and did it work).
I would recommend creating a private announcement list that the installer feature writes to.
This makes it easy to check that the install has worked (especially in a SOX environment where you won’t be the one running the script).

Sharepoint Warning

I have been investigating creating custom content types in Sharepoint and basing lists off of them.
I have been working with the feature xml documents.

There is an insideous bug that you need to be aware of: the name and the guid for a custom field must both be unique.
If you reuse the name of a field when creating a custom type then when the type is activated the duplicate field will be silently dropped – no warnings or errors.  This took me a day to track down – I was wondering why the view that I built on a list was missing some columns. When I checked these were thecolumns that I had used in an earlier prototype.

There is another catch – you may need to recycle the app pool between un-registering and re-registering features.  Sharepoint seems to prefer to use the cached values rather than the newly supplied ones.

The above was exasperated by the substandard documentation supplied with the product.  While there is lots to read, it is incomplete and contains errors.

It appears that Sharepoint 2007 was realeased too soon – the internal design is not consistent (three styles of guid are required to register a content type!), the error handling is patchy – varies from excellent (exactly which field is incorrect) to vague (a field is wrong somewhere).

Perfect Storm 1.0

I have finally released the initial version of perfect storm.

This may be found here.

Tricks this has:

  • Creation of multiple outputs from a single model.
  • Custom xslt string functions to change case to Pascal, Camel, upper, lower
  • User specified “variables” may be inserted into the output.

Abuse of ConfiguationSettings (Ultimate config section).

This article gives a useful hint on how to implement your own configuration setting in a generic manner.

However I think that I have refined the technique.
What I always wanted was direct read only XML access to the config section.

The following gives exactly what I want:

    public class XmlNodeConfigSection : IConfigurationSectionHandler
    {
        public object Create(
             object parent,
             object configContext,
             System.Xml.XmlNode section)
        {
            return section;
        }
    }

When registered as follows in app.config:

section name=”mysection” type=”mynamespace.XmlNodeConfigSection, myassembly”

Allows the following to return an XmlNode:

(XmlNode)ConfigurationManager.GetSection(“mysection”);

This will be null if the requested section does not exist.

You are free to use XPath expressions (&c) to get at the data!

Sharepoint Thoughts

Sharepoint looks to be a very useful platform to develop on.

It has a large amount of internal consistency problems:

The object model uses different names for the webs of the application to the user.
Documentation is patchy – terminology that you are told to avoid is part of the object model.
Negatively named attributes.

The object model can be inconsistent: why does adding a list return a guid whilst adding a site returns the new site?

The built in web services are kind of functional but I would always recommend defining your own:

  • They will not break on upgrade (or at least the interface won’t change)
  • They have a defined interface rather than requiring large blocks of CAML

Web Service change in .NET 2

It has come to my attention (during a sharepoint course) that there has been a small change in the .NET 2.0 implementation of web services.

Async methods now come as an event hander (for the end) and a method for the start.
This is much easier to use that the .NET 1.1 version.