Saturday, October 27, 2007

Creating a new form in a list by copying an existing form (in code)

To copy an existing form in a WSS list, and to add a new content editor web part to that list, use the SPFile class (not the SPForm collection of the list):

//Copy the NewForm.aspx to NewForm_new.aspx
string formPath = "Lists/ClientTest/NewForm.aspx";
string newformPath = formPath.Replace(".aspx", "_new.aspx");
SPFile form = web.GetFile(formPath);
form.CopyTo(newformPath, false);

//Get a reference to the new form, and create a new content editor web part containing onload JavaScript
SPFile copiedForm = web.GetFile(newformPath);
SPLimitedWebPartManager wpManager = copiedForm.GetLimitedWebPartManager(PersonalizationScope.Shared);

//Create the new web part
ContentEditorWebPart wpContent = new ContentEditorWebPart();
XmlDocument xmlContent = new XmlDocument();
XmlElement el = xmlContent.CreateElement("El");
el.InnerText = "";
wpContent.Content = el;
wpManager.AddWebPart(wpContent, "Main", 0);

The JavaScript adds an onload handler to the page, allowing for behaviours to modify the content of the standard list form for example.

Thursday, October 18, 2007

Error in Custom Document Library View

When creating custom document library definitions using the view files output by the SharePoint Solution Generator, you may see the following error on the custom view pages in an instance of the libary:

An error occurred during the processing of ....... Only Content controls are allowed in a content page that contains Content controls.

This is caused by invalid text in the ASPX file - the solution generator adds a comment XML node to the top of each view file, and this needs to be deleted before deploying that view.

Checkin Page Shows Error For Document Library

Have been very busy creating lots of solutions to define a raft of lists and document libraries. One technique I have experimented with is as follows:
  • Manually define the site containing the lists
  • Use the SharePoint Solution Generator to create schemas for the lists
  • Run my own tool across these schemas to generate site column and content type definitions. The tool also removes some of the invlaid attributes in the schema field definitions that are created by the solution generator (I'll publish the tool here sometime soon)
  • Create solutions and features in Visual Studio using these XML definitions.
This has been saving me lots of manual effort in creating all the necessary XML. My reason for not using the VSeWSS projects for list definitions is I prefer control over the feature and manifest files, so that I can add other elements where necessary.

I came across an issue with a document library created using one of the custom list definitions. Everything seemd to work in the document library except for checking in a document - the checkin.aspx page simply displayed an error stating

"Value does not fall within the expected range"

Don't ya love that one!! Lots of investigation uncovered the cause - a malformed content type. The document library used one custom content type, and one of the field elements in the field section of the document library schema.xml file had a mispelt name attribute. Amazing that I could still add a document, and could edit the metadata values!

Thursday, August 30, 2007

Visio Stencil of SharePoint Design Shapes

When creating site and application designs for SharePoint, I have wanted to illustrate the elements that comprise the solution's architecture.

Diagrams at this level are very valuable for explaining the proposed design to a client, and also for summarising the elements involved ("a picture is worth....").

So I have created a Visio stencil containing a few useful shapes.

See an example of the shapes, and download the stencil, from here

Wednesday, August 22, 2007

Debugging SharePoint Custom Code

Great article about debugging SharePoint applications. It also suggests designing code to facilitate debugging, which seems a very sensible idea to me (particularly when combined with the idea of designing to "fail fast", thereby ensuring that exceptions are not hidden by the code)

One MOSS site I developed recently includes several event handlers and timer jobs. Each of these includes a common class to write error messages to a custom list in the site when exceptions occur. Having a central location within the site to monitor error message has proven effective - one advantage is that I can set up alerts in case of exceptions.

Using the facilities native to SharePoint (liist, alerts, etc) simplifies development and gives huge flexibility in using the resulting data.

Wednesday, August 8, 2007

Email and SharePoint are not Competitors

A discussion following on from a presentation I recently attended (on the use of SharePoint in business) raised the opinion that email is a competitor to SharePoint in terms of business use. The basis of the argument was that people in an organisation either can use SharePoint for their collaboration or they can use email.

I disagree. SharePoint is now very much email-enabled, with the ability to send alerts or emails from custom code, and to receive emails into lists. The ideas in the discussion may have been based on the belief that users are required to interact with the data contained in a SharePoint site only through the site's web pages.

Certainly the users will need to perform some actions through web pages, but it is possible without much work at all to implement a business process in SharePoint in such a way that the users can continue to use emails for many of the operations they perform. An email sent to a SharePoint list can be interpreted by event handlers on the list, which could act on information in the email and add or edit data in the list.

What I have found is that architecting solutions in SharePoint requires a different vision than when developing in ASP.Net. One of the key points is to build on SharePoint's strengths - think about using lists for storing data (for example, store temporary data for an application in a list rather than in a database table).

Strange Results When Adding Web.Config Values

SharePoint provides a programmatic way of editing existing values and adding new values to a web application's web.config file - through the use of the SPWebConfigModification class (defined in the Microsoft.SharePoint.Adminstration namespace).

There are plenty of posts around explaining how to use this class, the basic pattern for adding a custom value being the following:

        private void AddWebConfigEntry(
string keyName, string entryValue)
        {
            SPWebConfigModification modification 
= new SPWebConfigModification
                 (string.Format("add[@key=\"{0}\"]", keyName)
                 , 
"configuration/appSettings");
            
modification.Owner Constants.FEATURE_NAME;
            
modification.Sequence 0;
            
modification.Type SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            
modification.Value entryValue;
            
_webApp.WebConfigModifications.Add(modification);
            
_webApp.Update();
        
}

Wen I first wrote and used this function, I found that the key was correctly added to the web.config file, but was not being removed by a similar deletion function I wrote. And everytime I called this AddWebConfigEntry function, a duplicate entry was written to the file.

Turned out that I had missed the escaped double quotes in the first argument of the SPWebConfigModification constructor call. What made this a tricky effect to fault-find was the fact that the new web.config entry was being created.

So the morale of this tale is - be VERY careful with the arguments to that constructor!