SharePoint List Validation

I had a need to be able validate a date against another date on a list when it was created, basically I wanted the second to date to be on or after the first date. Traditionaly, this sort of thing was handled through event receivers attached to the list, but it always felt like overkill.

It was only when looking through the List Settings page that i noticed the Validation settings section that i’ve never really looked at before. This section allows you to create a Formula (think Excel) using multiple colums. The formula is validated at list entry time and if the formula returns false, the user message you specify is displayed to the user.

My particular validation was around ensuring that the Position End Date (if populated) was on or after the Position Start Date, to do this through the Validation Settings page, I add to enter the following formula:

=OR([Position End Date]>=[Position Start Date],(COUNT([Position End Date])=0))

This is showing an OR condition, where the Position End Date must be on/after the Position End Date OR the Count of the number of entries in the Position End Date is 0. This was the only way I found of checking whether a date had been emptied as empty string or null didn’t seem to work, presumably because of DateTime type constraints.

This worked fine for manually configuring validation on lists that already exist, but if you want to do this at list provisioning time, you can add it in the list schema just after the ContentTypes node, just like this:

    <ValidationMessage=The position end date must be on or after the position start date>

=OR(ExpPositionEndDate >= ExpPositionStartDate,(COUNT(ExpPositionEndDate)=0))

</Validation>

Note, that you have to use the internal name for the columns when configuring through the schema.xml.

InfoPath form deployment errors to SharePoint

I’ve spent a little while trying to get to the bottom of a deployment problem when updating an existing InfoPath form that had previously been deployed to a SharePoint site via a feature. The change was a simple textual change, adding some descriptive text to the top of a form. Simple you might think…

Actually making the change was easy enough, I opened the design form from within Visual Studio. Interestingly even though I had double-clicked the file from within my source tree it was actually opening it from a path that was stored within the file. Saving the form template to my source tree has got around that. Its something that I wouldn’t have noticed apart from the fact that the location it was actually opening it from was write-protected and hence it couldn’t save it. Otherwise I would have made my changes and blindly checked it in thinking I was actually checking in my files. It would have appeared to have worked but the actual changes would have been in a file that wasn’t under source control!

I then published the form template to where it was stored in TFS in my feature folder. I wasn’t sure what options had been previously used during the original publishing so I just accepted the defaults (this was where I went wrong…). I then updated my wsp and upgraded my feature. Upgrading didn’t work as the file is actually uploaded into SharePoint via a module definition so I had to change my deployment to do a retract/redeploy instead. I realised this as post upgrading nothing seemed to have changed within the form. After doing a retract/redeploy I now got something different which was basically a ‘form has been closed’ error on trying to access any workflows that were using this form.

Doing some digging using the following useful stsadm command:

stsadm.exe -o verifyformtemplate -filename <complete path to your xsn including the name.xsn>

I got the following back:

FatalErrorNoThrow : This form template has not been correctly published to be browser-enabled. Open the form template in InfoPath Design mode, and click Publish Form Template in the Design task pane. Follow the steps in the Publishing Wizard to republish the form template, and then try again.

Well I did this many times, trying different combinations of settings, even trying to modify the access location to be the path to the installed feature in the 12 hive. I thought this might be something to do with the fact that it was originally trying to open it from a different source location and I thought it might be something to do with me moving it to my source location however nothing seemed to work. I then did some more searching and came across a really good post by Sahil Malik that explains the correct process to follow to deploy InfoPath forms via features, and in there he mentions leaving the access path blank, as this information is stored in the feature. This was the key thing that I was doing wrong. It appears that anything you put in the Access Path property during the Publishing path overrides what is supplied in the feature and stops the form from deploying correctly, in fact if you go to the Manage Form Templates page within Central Administration you will see your deployed form stuck in a Status of Installing and the Workflow enabled option will be No.

Here is a link to Sahil’s post as it really explains in good detail the correct process to follow to deploy InfoPath forms using features:

http://blah.winsmarts.com/2008-8-Deploying_InfoPath_2007_Forms_to_Forms_Server_-and-ndash_Properly.aspx

Blanking the access path and then rebuilding my wsp, retracting/redeploying and now everything works. Existing workflows have been updated and new ones pick up the new form too. Finally, and all I was doing was adding some text to the form… 🙂

SharePoint recurrence data schema

I have been hunting high and low for some definition of the schema used to populate the RecurrenceData field of an event in a SharePoint calendar. It seems to be one of life’s great mysteries…

Today, I finally stumbled across an msdn blog post that explains how to export SharePoint calendar events to iCal format files. I’m sure that this is the only post in the entire Internet (except for mine now of course…) that contains some really useful nuggets about what you need to set on your SPListItem when creating an event through code. I’ve included a link to the article at the end of this post, but just in case I’ve also copied a bit of it here…

<Updated> I’ve just added a section about deleting individual events from a recurring series. This took a bit of figuring out! </Updated>

Distinguishing between calendar item types

Calendar items in SharePoint fall into several categories. Single events are those which don’t repeat and only appear once on the calendar, while recurring events may show up any number of times depending on the recurrence pattern selected by a user. Either type of event may have a defined start and end time, or it may be an all-day event which lasts from midnight to 11:59 PM.

Furthermore, individual instances of a recurring event may be deleted or edited, creating a new event which takes its place. The event created by a deleted instance instructs the calendar not to render that day’s instance of the recurring event.

Calendar events can be distinguished by looking at the fRecurrence, fAllDayEvent, and EventType field values:

Type Description fRecurrence fAllDayEvent EventType
Single event An event created with the All Day Event and Recurrence checkboxes unselected. False False 0
All-day event An event created with the All Day Event checkbox selected. False True 0
Recurring event An event created with the Recurrence checkbox selected. Has a recurrence icon in the All Events view. Appears as a single master event on the All Events view, but as recurring instances on the Current Events and Calendar views. True False 1
Recurring all-day event Same as above, but with the All Day Event checkbox selected at creation time. True True 1
Recurrence exception Created by editing an instance of a recurring event. Has a strikethrough recurrence icon in the All Events view. True False 4
All-day recurrence exception Same as above, but created by editing an instance of an all-day recurring event. True True 4
Deleted instance of a recurring event Created by deleting a instance of a recurring event. Title is prefixed with “Deleted:” in the All Events view, and is hidden in the Current Events and Calendar views. True False 3
Deleted instance of an all-day recurring event Same as above, but created by deleting an instance of an all-day recurring event. True True 3

Understanding recurring events

Recurring events have a number of subtleties not found in single events. Most importantly, one recurring event item expands into any number of recurring event instances when it is rendered in the calendar view. Recurring events also make use of fields left empty in single events.

Certain fields are interpreted differently depending on whether the item in question is a recurring event or a single event:

Field Value for single event Value for recurring event
EventDate Start date and time Start date and time set for the recurring event when it was created, which may be an earlier date than the first instance of the recurring event.
EndDate End date and time End date and time for the last instance of the recurring event. For recurring events with no end date, this is a computed date several years in the future.
Duration The time in seconds between EventDate and EndDate. The duration in seconds of an individual instance of the recurring event.

Recurrence patterns and expanding events

Recurring events store the pattern used to display instances of the recurring event as XML in the RecurrenceData field. While this data is best used in a read-only fashion, the following are examples of the patterns you may encounter:

Recurrence type RecurrenceData field value
Daily every 1 days, no end date <recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><daily dayFrequency=”1″ /></repeat>

<repeatForever>FALSE</repeatForever>

</rule></recurrence>

Weekly every Monday, Tuesday, and Wednesday, end by 5/31/2007 <recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><weekly mo=”TRUE” tu=”TRUE” we=”TRUE” weekFrequency=”1″ /></repeat>

<windowEnd>2007-05-31T22:00:00Z</windowEnd>

</rule></recurrence>

Monthly the third Wednesday of every 2 months, no end date <recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><monthlyByDay we=”TRUE” weekdayOfMonth=”third” monthFrequency=”2″ /></repeat>

<repeatForever>FALSE</repeatForever>

</rule></recurrence>

Yearly every May 18, end after 10 instances <recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><yearly yearFrequency=”1″ month=”5″ day=”18″ /></repeat>

<repeatInstances>10</repeatInstances>

</rule></recurrence>

Deleting individual events from a recurring series

In order to delete an individual event from a recurring series, you actually need to create a new event and set a few properties on it to link it up to a specific instance from the ‘owning’ series. You will need to set the following properties (You need all of them!):

  • MasterSeriesItemID
    • Set this to the ID of the owning calendar list item
  • UID
    • Set this to the UID of the ownding calendar list item. If you haven’t populated this column in your owning list item, you’ll be having all sorts of problems already…
  • EventType
    • Set this to 3 to mark it as a deleted record
  • fRecurrence
    • Set this to 1
  • fAllDayEvent
    • Set this to the fAllDayEvent property of the owner calendar list item
  • EventDate
    • Set this to the date of the event instance you want to delete
  • EndDate
    • Set this to the date of the event instance you want to delete
  • RecurrenceID
    • Set this to the date of the event instance you want to delete. (Yep, this is the one that caught me out…has to be set to a datetime and NOT an ID)
  • Title
    • Set this to the title of the owner calendar event, but prefixed with Deleted:

When you have done this, you should now see an additional event in the All Events view of the calendar with a title of “Deleted: Name of your event” and the date of the specific instance. In the Calendar view, the specific instance should be invisible. This means that if you want to undo your deleted instance, you simply delete the extra list item that you have created and it will reappear!

Day 1 of the SharePoint 2010 Evolution Conference

I turned up nice and early at the Queen Elizabeth II Conference Centre to settle in and partake of the lovely breakfasts that they provide. I promptly managed to drop jam on my jeans…not the best of starts, but I managed to clear it off with a bit of water and no-one seemed to notice so I think I got away with it…

The first day started with the key note, hosted by Steve Smith, Eric Shupps, Spencer Harbar and Brett Lonsdale, summarising the ‘Evolution’ of SharePoint since it’s roots in Tahoe, through SharePoint 2003 (which is when I was first introduced) and then SharePoint 2007, and then hinting at what is to come. All very well but where’s the new stuff, I hear you cry. Rather than go through every session I attended I’m just going to pick out the highlights, if you want my insights on each of the sessions, follow me on Twitterand look at what I tagged with #spevo.

The first session I attended was Eric Shupps’“Introduction to SharePoint 2010 development”, not a session I was planning to go to (I’m not going to dwell on the effects the Icelandic eruption had on the conference (read this postby Eric for a real good insight!), lots of people couldn’t make it, lots of people stepped in and many people presented far more sessions than they were intending to, shame the other guys couldn’t make it but there’s always next year!). As it was, Eric really did lay the foundations for the rest of the conference, many of the things he showed us really became a recurring theme throughout, such as:

  • Visual Studio F5 deployment
  • Sandbox solutions
  • SharePoint deployment configurations
  • Client object model
  • Native linq for SharePoint

Chris O’Briendid a really good session on application lifecycle management, which was all about how to upgrade your solution beyond its initial 1.0.0.0 release. Before getting into the upgrade process, he started off listing a few of the new development ‘features’ offered by Visual Studio 2010 and SharePoint 2010.

  • Ability to import a SP2010 wsp into VS2010, which will ‘disassemble’ the wsp into component features for content types, columns etc
    • Advantages
      • Generates features for everything
      • Quick way to get at the xml for specific columns and content types
      • Granular, you can select which pieces from the wsp you wish to import
    • Disadvantages
      • All content types are generated, including system ones
      • Cannot handle bcs external content types, code workflows, SP2007 wsp’s
      • Web part properties are saved as binary, so are difficult to manipulate
  • Event receivers on specific lists
  • Property bag objects
  • Web template definitions
  • Custom action for adding javascript to a page
  • Upgradeable feature framework

The upgradeable feature framework essentially defined the rest of his session. The mechanism hangs off the version property that was always present in the feature xml but never did anything, now its extremely important (if you didn’t have a version specified in your xml, version 0.0.0.0 was implied). You now have some new xml that can be added to a feature where you can specify what upgrade actions to take and what version range to apply your upgrade actions to. Through the xml you can add columns to existing content types, deploy new items through adding pointers to new elements.xml files, repoint files to new locations. There is also a featureupgrading event that you can attach code to, to do just about anything else. See this msdn articlefor further information on upgrading features.

Eric was back for another session on customising the visual studio 2010 sharepoint deployment process. This was of interest to me as the 2007 process is somewhat ‘clunky’! The key points I picked out of this was how easy and consistent the whole deployment process is, its simply F5 and that’s it. Visual Studio packages all your features into wsps, retracts them if they are installed, deploys, activates and attaches the debugger all in one hit. Microsoft have made the whole process fully extensible, so you can do whatever you want through code. You can use the Microsoft.VisualStudio.SharePoint.Commands api to create custom solution commands to add into visual studio through vsix project types.

The other highlight of the day for me was SharePint. Had a great time catching up with some friends I hadn’t seen for a while. Didn’t stay too late, as its a long way for me to get home and an early start to get back again in the morning. Overall a great first day, and I was looking forward to day 2…

Response.End terminating page events within a sharepoint page

I had a need to be able to present the user of a website with a prompt to open/save a pdf that had been dynamically generated based on inputs from the user during the completion of a form.
I wasn’t able to navigate away from the page where this option to download the pdf was presented to the user as i needed to remain within the context of the particular section within the form. Therefore the easiest way to provide the open/save option was through modifying the Page.Response as follows:

Page.Response.ContentType = “application/pdf”;

Page.Response.AddHeader(“content-disposition”, “attachment;filename=” + this.FormControl.FormDefinition.Name + “.pdf”);

Page.Response.Buffer =true;

Page.Response.Clear();

Page.Response.OutputStream.Write(PdfBuffer, 0, PdfBuffer.Length);

Page.Response.OutputStream.Flush();

Page.Response.Flush();

This worked fine, the user would click on a download button, the open/save box would pop up and the pdf would be streamed exactly as I wanted it. However, when they closed the open/save box and returned to the page with the download button on, none of the buttons on the page would work anymore, the page was effectively ‘dead’. The confusing part, was that if I used exactly same html, code etc on a page outside of SharePoint I didn’t have any problems at all. This was specifically related to pages hosted within SharePoint.

After digging around I found a comment buried down within a thread (http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/107b2c17-07fe-4a15-ad81-dcb31e1e9c84/#b5295204-c20a-4910-ab4b-d870ac09f687) where the following solution was proposed, and it works a treat:

In the page where your ‘download’ button resides, add the following code where you create the button control:

downloadButton.OnClientClick = “this.form.onsubmit = function() {return true;}”;

If using a LinkButton instead of a Button add the following instead:

exportButton .OnClientClick = “document.getElementsByTagName(\’form\’)[0].onsubmit = function() {return true;}”;

And everything then continues to work when you return to your page. The reason appears to be based on the fact that Sharepoint updates some kind of timestamp hash on the form before it is actually submitted to the server. This is done in order to prevent the form from being submit more than once if the user clicks before the Postback is completed, which is a good thing – except when trying to do what we are trying to do here.

Improved CAML IntelliSense

Don’t know why I missed this but its an essential add-in for Visual Studio 2005/2008. This guy has taken the core SharePoint schema files and extended them to add all that information from the SDK that is notoriously difficult to find. He’s done this by getting as much information as possible and sticking it in xs:annotation elements, and replacing as many xs:string types with enumerated types as possible so that we get the possible valid values.

A couple of examples that will make you go and download this straightaway:

  • When selecting a true/false type, he pops up an annotation that lets you know what type of true/false value you need, either TRUE, True, true etc etc
  • When you are creating a ListInstance and start typing the TemplateType, not only does it give you an enumeration of the various integer values that you can enter but it pops up an annotation describing what each one is

I honestly think that if you are doing SharePoint development this could easily save you a couple of hours a week!

Here’s a link to his post that describes it in more detail and where you can download the files : CAML.Net IntelliSense

Default values on a content type not set in a page layout

Now this took me some time to figure out…

Basically the problem I was having was that some of my fields, specifically date time fields, weren’t being populated with their default values of [Today]. I had set the default value correctly on the field and assigned the field to my Content Type which I had then applied to my Pages library (all through a Feature). Everything looked fine until I created a page, and hey presto all my fields were empty.

I thought at first it was to do with how I was provisioning my fields in xml but everything appeared fine, I then added a date time field through the GUI with a default value to my content type to make sure and that didn’t work either!

I then started looking at the settings on my Pages library to see if anything there was wrong. I did have multiple Content Types assigned to my library so I thought to avoid confusion I’d remove all the other Content Types and leave mine as the default. I created a page and all my default values were populated!! Aha, I thought, there’s a conflict somewhere or a corrupt Content Type. So I added them all back in, testing after each one and everything worked!

After further testing, it turns out that default values on fields in a Content Type on a page layout will ONLY get populated on the DEFAULT Content Type on a library. Definitely seems to be a bug… and is a problem if your multiple content types each have fields with default values, luckily for me that wasn’t the case.

An unhandled exception occurred in the user interface. Exception Information: OSearch (SearchAccount)

Had this not very nice error whilst trying to start the search service on my single server SharePoint installation through Central Administration:

An unhandled exception occurred in the user interface. Exception Information: OSearch (SearchAccount)

This took me a while to figure out as it appears that even though I wasn’t using a Domain account, the UI seems to expect a ‘Domain format’ account, so entering DevMachine\SearchAccount worked!

Nice…

Day 3 of the SharePoint European Best Practices Conference

The final day of the conference got off to a great start when I discovered I had won a Sat Nav in the prize draw. Can’t complain!

The first talk I went to was Maurice Prather’ssession on best practices for creating, deploying and managing list and item events. This was very interesting as, not matter how much you think you know about this topic, there were plenty of useful nuggets to take away. One common theme that surfaced again in this talk was being careful what you package in a wsp to minimise the upgrade impact. I think the best approach is to logically group together bunches of functionality so that on an upgrade you will upgrade only the functional area you have changed rather than say all the event receivers. Other best practices:

  • In general its better to bind event receivers to content types rather than lists, caveats being some lists have multiple content types so its better in that case to bind to the list. Also, a document added event only uses the default content type
  • If PartiallyTrustedCallers are not allowed on your event receiver class you may get skewed results
  • Use DisableEventFiring and EnableEventFiring in your event receiver class to control recursion in events and prevent the ‘fan’ effect
  • There is no Site Added event, but if you have an auto-activated feature on a site, you can use the featureactivated event to simulate site added

The next session was Spencer Harbarand Andrew Connell’ssession on launching your MOSS publishing site. This had some repeated content from Andrew’s previous session on building high performance solutions but it’s such a broad subject that he was able to dig deeper in other areas. A few things I noted down from this event:

  • To get rid of the ActiveX warning message that you get the first time you go to a SharePoint site, see MS KB 931509
  • To get the ActiveX warning message to reappear after you have accepted it, go to IE settings->Manage Add-ons and disable the namectrl class and then delete it, though this didn’t seem to work in Andrew’s demo!
  • The ViewFormPagesLockDown feature needs to be reactivated when changing the anonymous settings on a site collection
  • Remember to enable AND configure your page output caching
  • The Blobcache maxsize in the web.config is in Gigabytes NOT Megabytes

During the lunch session got a chance to see a really nice Silverlight demo of a SharePoint site being tested in schools in Leeds by Andrew Woodward. It was very, very nice and a lot of people came away very impressed. A few people asked about the accessibility of using Silverlight which always happens. My feelings about accessibility is that its a means to get the core information out of the site to the user, so why can’t you have one mechanism for one and another for the rest, I get fed up of trying to deploy a single (often lowest common denominator) solution…

After lunch it was time for Chris O’Brien’ssession on the various approaches to and the best practices for deploying SharePoint sites through multiple environments. Been looking forward to this one, as I have a lot of time for Chris (we worked together for a while a few months back) and I have been helping him a little with the Kivati piece of his talk. One thing I noted during the demo was that his Content Deployment Wizardcan now import multiple .cmp files in one go. I’m pretty sure it hasn’t always been able to do that, plus you can command-line script it now which is very handy. I’m thinking of writing a deployment post myself to cover integration of Powershell and the command-line content deployment wizard to give you a nice complete deployment solution… Very good talk by Chris, he comes across very relaxed on stage and I’m pretty sure that he had the most questions after a session than a lot of the others which shows the interest in this area. I have to say a big thanks to Chris for pimping me out as the ‘Kivati guy’, hopefully that can only be a good thing, though the phone hasn’t rung yet 🙂

Final session of the day was Eric Shupps’session on high performance programming for SharePoint developers. This was very interesting as it went into quite a low level at some points and the demos gave good timing comparisons for various techniques to get list items. An interesting thing he mentioned is that every piece of data in a SharePoint site collection, no matter where it is in the site collection all goes into one SQL table, which emphasis the importance of optimised data access. A few tips here:

  • Use the Search API for cross-site queries on lists, use targeted scopes to allow for more frequent indexing. I really like this idea and can see lots of uses, and not only that but the performance is really good, the only caveat being that the data could be stale (depending on the frequency of your index) so it may not fit all situations
  • Get your data either via web services or search api and then use LINQ to provide a relational data layer to aggregate data across lists

We then had the Q&A session for developers and yet again the panel all worked so well together on stage so that not only was it very informative but also very entertaining. My two questions got answered, one being what’s the best way to monitor that your events are still firing as expected, and the answer was that when an event fails there is nothing logged, so you’d have to implement some sort of tracing/CRUD mechanism that would occasionally run, maybe overnight?, so that you were testing in a controlled fashion. Now I’ve thought about this, and probably the only way to do this would be to have a test harness that would interrogate a list that has an event attached, before triggering an event it would write to a SQL table, the event would then be responsible for updating the SQL table. That way you could see if any weren’t firing? Future project for me I think…

My other question was about how many gallons exactly was Eric’s hat, and the answer is that there is no such thing anymore there are only high and low ones now apparently but he thought the question was funny, at least he didn’t hit me anyway…

SharePint in the evening was great, chatted to loads of people and really enjoyed myself. Really had a great time over the last 3 days and will definitely go again, I just need to convince Chris to talk about Kivati again and then convince him that he needs me to travel with him to the next conference…;-)

Day 2 of the SharePoint European Best Practices Conference

Day 2 in sunny’ish London and a lovely start to the day with croissants and tea. I got there nice and early, had a wander around and met some nice people, including Philip Broadbery from a growing company called Fernhart New Mediathat seems to be going places…

The first talk I attended was Eric Shupps’talk on designing and deploying enterprise branding solutions using custom site definitions. This seems to be a contentious issue between some of the MVP’s with some interesting arguments in the Q&A session at the end of the day regarding declarative versus code solutions. I’m leaning more towards the code solution at the moment, but my recent experiences with site definitions has debunked a number of myths around their complexity and I’m not as scared of them as I once was… Eric was a very entertaining talker, a large presence on the stage, particularly in his large cowboy hat! Couple of useful tips I got from this included separating out the features and site definitions into different wsp’s. Quite often they get bundled together in deployments into one solution but what this means is that when you upgrade, the infrastructure will always recycle the app pools because you are re-provisioning onet.xml files etc, when quite often they haven’t changed and its only really the features that have changed. Having them separate alleviates that problem and makes live deployments less ‘impactful’. Another tip was a pointer to Patterns and Practices SharePoint Guidanceon codeplex which is a great resource for MOSS developers.

Next talk was by Ben Robbon customizing the Search UI in SharePoint 2007. This was actual quite a useful talk, as it was particularly pertinent to some problems we were facing with my current client. He suggested using the out-of-the-box search web parts where possible, and customising them using Xslt rather than re-inventing the wheel. He mentioned a few SEO things to help your sites, including organising your sites logically and having an up-to-date sitemap file in the root of your site. One suggestion was to have a custom timer job that uses the sitemap provider on the site collection to regenerate the sitemap xml file and then re-copy to the root.  A simple idea, but one I don’t think I’ve seen done anywhere…

Todd Bleekerwas up next to talk about best practices for creating custom field types. The amount of information that this guy can cram into a session is amazing. I was physically exhausted afterwards…! Some really good content here (too much to remember, let alone post but I should get that DVD so I’ll follow up). His main recommendation was to utilise User Controls for the UI of the control class of a custom field type and use a Value class to enable serialisation into a friendly object. This gives you the nice logical separation of ui/code and also the design surface and intellisense within Visual Studio. This is instead of using the rendering template xml that is currently the only documented way of doing this. Use the FieldEditorUserControl property in the fldtypes.xml file to point to your user control.

Andrew Connellswiftly followed with a talk on building high performance solutions on MOSS 2007. Again another talk crammed with content. Key things I picked out of this, was to minimise the perception of page load by using a lazy-load core.js (see Microsoft Knowledge Base Article 933823); look at image stitching/clustering to save on http requests for page furniture. This sort of works along the same principles as sprite batch files, where your images are in one long panorama, that you index with an offset of the image width, though its done via cropping in css. He suggested a company that has some useful tools to help with this as I imagine it would be a bit of a pig to do manually. The company was Get Run-time Page Optimizer.Another big area that can lead to rapid improvements is IIS Http compression. Dynamic compression level isn’t set by default for IIS7 sites, if you start by setting the level at 9 (10 is the max, but the CPU hit just isn’t worth it) and then scale it down until your cpu usage is acceptable it can give you performance improvements of 20%+ just by ‘checking a box’…

That was the last talk of the day but it was followed by a Developer Panel Q&A session which was quite interesting though difficult to write down. Lots of interesting talks about site definitions versus feature stapling, defining meta data at the site level (consensus seemed to be, set it on the default page of the site as its essentially the same thing). Hope these sessions are included on the DVD we get. Will let you know!

Anyway more fun tomorrow!