SharePoint 2009 Comes With Ribbon Interface?

The next version of SharePoint, aka SharePoint 2009 or Office Server 14, is scheduled for release sometime during the second half of 2009. Various blogs have already listed some of the presumed new features, like these:

  • 64-bit only
  • Silverlight UI / Web Parts
  • Better support for dealing with large lists (must-have!)
  • Groove integration

Recently I heard of a new feature that I hadn’t seen on any of these lists: SharePoint 2009’s default web interface will be using the (in)famous Ribbon interface. I was told this information comes from a SharePoint Product Manager at Microsoft, so it should be reliable.

Now I don’t really know what to think about this. I still have a love-hate relationship with the Ribbon ever since Microsoft released it with Office 2007. For basic Office usage it works very well, but for some tasks it find myself scrolling between Ribbon tabs like a madman.

On the other hand, SharePoint 2007’s UI isn’t that good either. The menus are all over the place and rather complicated, especially for first time users. Use of a Ribbon could improve on this. And considering the fact that SharePoint (i.e. Microsoft Office SharePoint Server) belongs to the Office family, it makes perfect sense to give it an Office-like interface. This would definitely enhance the integrated experience.

Now that I think about it, Microsoft’s Office website has been using a Ribbon-like interface for some time now and I must admit it looks nice. Maybe that’s the exact same Ribbon that’s going to end up in SharePoint 2009? Who knows… Maybe they’ll even implement it using Silverlight, so it will respond to my mouse’s scroll wheel, so I can continue that scrolling between Ribbon tabs like a madman πŸ˜‰

Update: I’ve received several e-mails from people claiming they already have the Office 14 alpha bits and they all confirm SharePoint 2009 / Office Server 14 is using the Ribbon for its menu’s.

Finally arrived: “Concurrent Programming on Windows”

Last June Joe Duffy announced that he had submitted the final manuscript for his (then upcoming) book Concurrent Programming on Windows to his publisher. Since then I had been anxiously waiting for it to arrive. Well, yesterday was the big day. The mailman delivered a big package and to my surprise it was Joe’s book. I had it on pre-order for some time and hadn’t expected it to be such a big book. OK, I knew it was going to have around 1000 pages, but still…

Ofcourse I haven’t been able to read the whole book yet, but I’ve scanned through it and I must say that I’m really impressed by it. It really covers many, if not all, aspects of concurrent programming on Windows. Joe has divided his book into four parts. In the first part he explains what concurrency is at a high level, which is great to get you started. In the second part he then thoroughly discusses fundamental platforms features, inner workings and API details. Here you’ll read everything about threads, thread pools, synchronization, asynchronous programming models and the lesser-known subject of fibers.

Actually, one of the chapters that immediately caught my eye was the one in which he discusses why fibers aren’t supported in the .NET Framework. As it turns out Microsoft planned to add fiber support to the CLR 2.0 so SQL Server 2005 could continue running in its "lightweight pooling" mode (a.k.a. fiber mode) when the CLR was hosted in-process. However they decided to completely remove it due to difficult bugs and schedule pressure. Joe gives some nice background info on this and tells you why it isn’t a good idea to try to use fibers from managed code yourself (i.e. by using P/Invoke).

The third part of the book then covers common patterns, best practices, algorithms and data structures that emerge while writing concurrent software. Here you’ll read about concurrency hazards like deadlocks and race conditions, data and task parallelism and performance and scalability. The final part of the book then discusses overlapped I/O, I/O cancellation and GUI threading models. All in all a very complete and thorough treatment of the subject of concurrency.

As a bonus Joe added two interesting appendices. The first one focusses on designing reusable libraries for concurrent .NET programs and the second one discusses the Parallel Extensions to .NET. Although this last appendix is very interesting and extensive I’m still a bit disappointed by it. I had expected the development of Parallel Extensions to go a bit faster and had hoped they would be released by now, so Joe’s book would include full coverage of this subject. Because of the current state of the Parallel Extensions (currently only some CTP’s have been released, although some of it is scheduled to appear in .NET Framework 4.0) the appendix might (well… most probably will) be outdated very soon. Considering the popularity and importance of the .NET Framework and the multi-core future I expect these Parallel Extensions to become very popular. So coverage of them has to become an essential part of this book. So expect a second edition of Concurrent Programming on Windows to arrive in the near future πŸ˜‰

Well, to conclude things: Concurrent Programming on Windows is a definite must-have for anyone having an interest in concurrent programming on Windows and can be considered an instant classic. No other book out there has such an extensive coverage of the matter. Just get it!

RIP: Patrick Tisseghem

I just heard the shocking news that Patrick Tisseghem, co-founder, managing director of U2U and Microsoft SharePoint MVP, has passed away last week. This is a great loss for the SharePoint community. The U2U website has this to say:

It is with deepest regret that we have to announce the death of Patrick Tisseghem, co-founder of U2U. Patrick suddenly passed away on Wednesday 3 September 2008 around 18 hours in Gothenburg Sweden due to a heart failure. Our sympathy and thoughts go out to his wife Linda, their daughters Anahi and Laura, and to his family. We are all deeply saddened by this tragic loss. We remember him as caring father as well as a driven and warm hearted colleague and friend. We miss you Patrick.

The last time I spoke to Patrick was a few months ago at the Dutch Microsoft DevDays 2008 in Amsterdam. After one of his sessions he helped me out with some SharePoint custom security trimmer problems I had.

I think he was a great guy and I always liked attending his presentations. Especially the funny, sarcastic, remarks used to make about SharePoint. My deepest condolences to his wife and daughters. Goodbye and thank you, Patrick!

Portal Navigation Properties Feature

Today my colleague Harmjan Greving pointed me to the Portal Navigation Properties Feature. I had never encountered this one before and as it turns out it is surprisingly undocumented by Microsoft.

So what does it do? Well, it’s a feature that comes with MOSS 2007 (unfortunately it isn’t included with WSS 3.0) that enables you to define per-site navigation settings in a declarative way. Until now I always used to write custom API code for this, that I executed from a feature receiver or a custom site provisioning provider.

The Portal Navigation Properties Feature itself is actually very simple. It contains no elements, but is only used to trigger the Microsoft.SharePoint.Publishing.NavigationFeatureHandler feature receiver, which does the real work, based on properties you specify. It is typically used from within a site definition file (ONET.XML), like this:

...
<WebFeatures>
    <Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">
        <!-- Portal Navigation Properties Feature -->
        <Properties xmlns="http://schemas.microsoft.com/sharepoint/">
            <Property Key="InheritGlobalNavigation" Value="True"/>
            <Property Key="InheritCurrentNavigation" Value="True"/>
            <Property Key="IncludeSubSites" Value="True" />
            <Property Key="IncludePages" Value="False" />
            <Property Key="OrderingMethod" Value="Automatic"/>
            <Property Key="AutomaticSortingMathod" Value="CreatedDate"/>
        </Properties>
    </Feature>
</WebFeatures>
...

Using Reflector I found out the following properties can be used with this feature:

Property Valid Values
IncludeInCurrentNavigation True / False
InheritGlobalNavigation True / False
InheritCurrentNavigation True / False
ShowSiblings True / False
IncludeSubSites True / False
IncludePages True / False
OrderingMethod Automatic
ManualWithAutomaticPageSorting
Manual
AutomaticSortingMathod 1 Title
CreatedDate
LastModifiedDate
SortAscending True / False

1 Please note the awful spelling error in “AutomaticSortingMathod”. Ofcourse this should have been “AutomaticSortingMethod”, but apparently someone at Microsoft forgot to run the spell checker over his/her code πŸ˜‰

Building a SPQuery ViewFields string

If you’re querying SharePoint content using a CAML query from code it’s a good habit to always populate the SPQuery instance’s ViewFields property. Otherwise the returned SPListItem instances might not contain any data for certain fields and throw an exception when you try to access those fields.

Specifying ViewFields involves creating a string of CAML FieldRef elements. For instance if we want our query to return items that contain data for the Title, Created and ID field we use this:

   1: <FieldRef Name='Title'/><FieldRef Name='Created'/><FieldRef Name='ID'/>

As you can see there’s some overhead of boilerplate markup involved. I’ve written a small piece of code that I always use to make my life a little easier. Today I happened to post this code in a reply I wrote on the MSDN forums and also decided to submit it as Community Content to the official SPQuery docs on MSDN. Then I thought I might as well share it with you here. So here it is:

   1: public static string BuildViewFieldsXml(params string[] fieldNames)
   2: {
   3:     const string TEMPLATE = @"<FieldRef Name='{0:S}'/>";
   4:     StringBuilder sb = new StringBuilder();
   5:     foreach (string fieldName in fieldNames)
   6:     {
   7:         sb.AppendFormat(TEMPLATE, fieldName);
   8:     }
   9:     return sb.ToString();
  10: }
  11:  
  12: // Use it like this:
  13: SPQuery query = new SPQuery();
  14: query.ViewFields = BuildViewFieldsXml("Title", "Created", "ID");
  15:  
  16: // Note that you can specify a variable amount of string parameters, i.e.
  17: query.ViewFields = BuildViewFieldsXml("Title", "Created", "ID", "Author", "Gender");

Yeah, you’re right. This piece of code isn’t exactly rocket science. But you might appreciate it anyway πŸ™‚

SharePoint Frustrations #1: The undocumented “IncludeTimeValue” CAML attribute

I’m planning on doing some posts about frustrating things I have encountered (and still do!) during my SharePoint development efforts. Here’s the first one:

Last year while working on a MOSS 2007 project for one of our customers I stumbled on what I thought was a bug in SharePoint 2007. I had created a custom list that was filled with Electronic Program Guide (EPG) information for the streaming video media that that site contained. I then created a Webpart that used ASP.Net AJAX to continually show the actual EPG information below the video stream.

In order to obtain the EPG items I used a CAML query to query the EPG list. The list was simply a custom list containing amongst others a column of type DateTime that was called "ProgramEnd". As the name suggests it contained the time the program ended. I then used the following code to create a query that was supposed to obtain the currently broadcasted item and all future items.

   1: const string EPG_QUERY_TEMPLATE = @"
   2: <Where>
   3:  <Geq>
   4:   <FieldRef Name='ProgramEnd' />
   5:   <Value Type='DateTime'>{0}</Value>
   6:  </Geq>
   7: </Where>"; 
   8:  
   9: SPQuery query = new SPQuery();
  10: query.Query = String.Format(EPG_QUERY_TEMPLATE,
  11:     SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)); 
  12: // ...

To my surprise this query always returned too many items. Further investigation showed that time part of the query seemed to be ignored completely, so it returned the items as if no time was specified! So instead of getting the current item and all future items it returned all items broadcasted for that day.

After wasting a lot of time debugging, using the U2U Caml Query Builder and looking for an answer / solution on the internet I gave up and wrote a quick hack around it, which fortunately wasn’t very difficult. It would just run the query and run the results through some additional code that checked the ProgramEnd DateTime field and filter out the wrong items, like this:

   1: SPListItemCollection results = ...; // The results from the query mentioned above
   2: // Trim the results to only include the current and future items
   3: List<SPListItem> trimmedItems = new List<SPListItem>();
   4: foreach (SPListItem result in results)
   5: {
   6:     DateTime programEnd = (DateTime)result["ProgramEnd"];
   7:     if (programEnd >= DateTime.Now)
   8:         trimmedItems.Add(result);
   9: } 

Fortunately this worked just fine and the customer was happy. I was not… 😦

Today while surfing the Net I stumbled on this entry in the MSDN forums, from which I learned it wasn’t a bug, but that you need to included the "IncludeTimeValue" attribute to the CAML query, like this:

   1: <Where>
   2:  <Eq>
   3:   <FieldRef Name='programEnd' />
   4:   <Value Type='DateTime' IncludeTimeValue='TRUE'>
   5:    2008-07-30T12:00:00Z
   6:   </Value>
   7:  </Eq>
   8: </Where> 

If only I had known it was this simple… What bothers me is that this little, but very important attribute seems to be totally undocumented. I couldn’t find any information about it in the WSS / SharePoint SDKs.

Ofcourse once I knew what to look for I found some other blogs and forums mentioning this issue. It turns out the UCSharp blog had already blogged about this way back in October 2007, only a few months after I searched for it. Even Karine Bosch, U2U’s "CAML Girl" and author of the famous U2U CAML Query Builder, says she only recently found out about this. Fortunately she has included support for the "IncludeTimeValue" attribute in her latest version of the U2U Caml Query Builder, which I know a lot of SharePoint developers use to construct and test their CAML queries.

I also noticed that someone called puneetspeed has added some Community Content to the online SharePoint SDK’s SPQuery docs explaining this issue. So hopefully Microsoft will add information about the "IncludeTimeValue" attribute to the official SDK text in the near future.

Back from the DevDays 2008

Just arrived back from my visit to the Microsoft DevDays 2008 in Amsterdam. It was a great day and I’ve attended some interesting sessions.

I’ve uploaded the photos I took to my Flickr account, so check ’em out. I’ve also uploaded a small video of the “Holland Sport” bicycle race track we had at our booth. Check it out:

It was a very tiring day and I’m going to get some sleep now. I’ll blog about some more about the DevDays later on…

Attending Microsoft DevDays 2008

Tomorrow (well… in a couple of hours actually) I’m off to Amsterdam for the Microsoft DevDays 2008. This year I’m only going to attend the first of the two days. My employer, Atos Origin, is a Platinum sponsor for the event and we’ll be there with a big booth.

At our booth you’ll be able to compete in a fun bicycle contest and perhaps win one of the six XBOX 360 consoles we are giving away! Hope to see you there. I’m scheduled for booth duty on thursday morning. Yes, that’s during David Platt‘s great keynote on “Why Software Sucks”. Fortunately I’ve already seen this one during TechEd Developers 2007 in Barcelona last year and I also own an autographed copy of his book on the topic. But still I’m going to try to sneak away from the booth for a while πŸ™‚

As for my SharePoint interests I’m hoping to get a chance to speak with Jan Tielens and Patrick Tisseghem, who are both scheduled to speak at the event. I’ve got some burning questions about Custom Security Trimmers that I hope Patrick can answer.

Oh, and ofcourse I’ll take my digital camera and see if I can take some nice pictures of the event and post them here.

Do not reuse SPQuery!

Last week I was refactoring some of my SharePoint code. I stumbled on a loop that created a new SPQuery instance for each iteration. The code was something like this:

   1: SPList list = GetCommentsList();
   2: const string VIEWFIELDS = "";
   3:  
   4: foreach (string param in params)
   5: {
   6:     // Create fresh new SPQuery instance...
   7:     SPQuery query = new SPQuery();
   8:     query.ViewFields = VIEWFIELDS;
   9:     query.Query = BuildQuery(param);
  10:  
  11:     // And use it...
  12:     SPListItemCollection items = list.GetItems(query);
  13:     ProcessItems(items);
  14: }

As the value of the ViewFields property remained the same for each iteration I decided to create just one SPQuery instance and reuse it, like this:

   1: SPList list = GetCommentsList();
   2: const string VIEWFIELDS = "";
   3:  
   4: // Create just one SPQuery instance...
   5: SPQuery query = new SPQuery();
   6: query.ViewFields = VIEWFIELDS;
   7:  
   8: foreach (string param in params)
   9: {
  10:     // And reuse it...
  11:     query.Query = BuildQuery(param);
  12:     SPListItemCollection items = list.GetItems(query);
  13:     ProcessItems(items);
  14: }

To my surprise this code didn’t work! The first time the SPQuery instance was used it worked just fine. However, during the next iterations of the foreach loop it didn’t seem to get updated.

So, what have we learned today? Never reuse SPQuery instances!

Well… That’s not entirely true. You can reuse SPQuery instances for a very valid reason. If you use the RowLimit property you can limit the number of items returned in the query, which is useful for paging as seen in this sample code (taken from MSDN):

   1: using (SPWeb oWebsiteRoot = SPContext.Current.Site.RootWeb)
   2: {
   3:     SPList oList = oWebsiteRoot.Lists["Announcements"];
   4:     SPQuery oQuery = new SPQuery();
   5:     oQuery.RowLimit = 10;
   6:     int intIndex = 1;
   7:  
   8:     do
   9:     {
  10:         Console.WriteLine("Page: " + intIndex);
  11:         SPListItemCollection collListItems = oList.GetItems(oQuery);
  12:  
  13:         foreach(SPListItem oListItem in collListItems)
  14:         {
  15:             Console.WriteLine(oListItem["Title"]);
  16:         }
  17:         oQuery.ListItemCollectionPosition = 
  18:           collListItems.ListItemCollectionPosition;
  19:         intIndex++;
  20:     } while(oQuery.ListItemCollectionPosition != null);
  21: }

So, only reuse SPQuery instances if you use paging. If you change the actual CAML query you should create a new SPQuery instance for it.

No More *BEEP*

I might have happened to you too: make some error in a Windows virtual machine and your system will *BEEP* out loud. Not some nice and fancy WAV/MP3 sample, but a raw *BEEP* coming straight from your system’s motherboard. This *BEEP* does not respect your speaker volume and mute settings. And it will probably irritate most people who sit near you.

Fortunately getting the beep to shut up forever is relatively simple. Here’s how to do it:

  1. Open a Command Prompt window (in Vista make sure you open it using the “Run as administrator” option).
  2. Use the following commands:
    • To stop the Windows Beep Service:
      net stop beep
    • To make sure it never gets started again:
      sc config beep start= disabled

That should take care of them BEEPs πŸ™‚