About



Erik Burger is a .NET Consultant at Antares Informatisering, an outsourcing company based in The Netherlands. He refuses to specialise in a single programming language as a matter of principle, believing that being multi-disciplinary makes him a better developer. He's a strong advocate of Pragmatic Programming and a newbie enthusiast in Ruby and Rails.

View Erik Burger's profile on LinkedIn


Microsoft Windows SharePoint Services 3.0: Application Development


Disclaimer



All opinions expressed in this blog are solely those of the author and not necessarily those of Antares. You may use all the information provided here but please understand that it is provided "AS IS" and comes with no warranty of any kind.


62


PDC 2008 Sessions Available

I’ve just found out that all the sessions of the Professional Developers Conference (PDC) 2008 that took place end of Oktober are available on Channel9. Sadly, I wasn’t able to attend but this makes up for a lot!

The videos can be found here: http://channel9.msdn.com/pdc2008/. Also, keep an eye on the official PDC website here: http://www.microsoftpdc.com/.

Enjoy!

There is an -imho-  disturbing tendency amongst developers when it comes to applying coding and style standards, unit testing, duplication analysis and the like. The typical mindset seems to be “if my colleagues don’t do it, I won’t, either”. I know, I’ve been there as well. In fact, I am still there. But if you consider that most, if not all, of the tools we use for the abovementioned tasks can run perfectly fine on any workstation, why not set up a NAnt script? Or even your own local buildserver? The benefits seem obvious but for completeness’ sake, here are a few:

  • Creating and running Unit Tests allow you to be more confident in the quality of your code and therfor more productive. In addition, if your colleague changes anything, you will be able to catch possible errors before getting slowed down by them at a later stage.
  • Running analysis tools and acting upon their results will guide your development effort so you produce cleaner, leaner and better code.
  • Running integration tests before you check anything in will cause fewer merge conflicts and fewer errors caused by your code.

In conclusion, the code you check in will be of higher quality, practically bug-free and unobstrusive (that is, your colleagues will barely know it’s there..not from errors popping up anyway).

Chances are high that your efforts (or lack thereof, as you tend to spend far less time in fixing bugs) will be noticed. If your colleagues ask, give them your most enticing smile as you fire up your favorite browser and show them the build and analysis reports you create. Bask in the glory, enjoy the admiration.

Then, get everyone else to do it.

Personally, I have taken up the task of following my own advice by setting up a build and reporting “server” on my own workstation. If there will be any “broken windows” in the codebase, they won’t be my fault. Mostly.

Erik

P.S. The “broken windows” reference comes from the excellent book The Pragmatic Programmer by Andy Hunt and Dave Thomas. Yes, this is a blatant advertisement, but the book is more than worth it’s cost. It’s changed the way I look at software development and I’d strongly suggest getting your own copy.

For an internal project we were creating a number of custom List Definitions by editing the schema.xml files. When we opened an instance of the List Definition in SharePoint, the fields we had added did not show up in the View, New and Edit forms. Only the Title field was visible.

As it turned out, the schema.xml file contained the following xml:

<List xmlns:ows="Microsoft SharePoint" ... >
  <MetaData>
   <ContentTypes>
      <ContentTypeRef ID="0x01">
        <Folder TargetName="Item" />
      </ContentTypeRef>
      <ContentTypeRef ID="0x0120" />
    </ContentTypes>
  ...

According to Microsoft, the ContentTypeRef element “specifies a reference to a content type to associate with lists that are created through the list definition”. In this case the Content Types are Item and Folder. For a list of the default Content Types included in Windows SharePoint Services 3.0, and their content type IDs, see here. For some more information on Content Types, see the Introduction to Content Types in the MSDN Library.

Obviously (in retrospect) the Item and Folder Content Types do not contain our custom Fields, only the Title Field. Removing the ContentTypes element altogether solved the problem and made all Fields visible in the View, New and Edit forms.

Hope this helps.

Sometimes you discover a little gem that you just know you will be using over and over again. My latest discovery is implicit type conversion. Implicit type conversion basically allows you to convert any object to any other type. Note that not all conversions make sense.

As an example, let’s assume the following Field and FieldList classes:

public class Field<T>
{
  public string InternalName { get; set; }
  public string DisplayName { get; set; }
  public T Value { get; set; }
 
  public Field(string name, string displayName, T value) 
  {
    this.InternalName = name;
    this.DisplayName = displayName;
    this.Value= value;
  }
}
 
public abstract class FieldList
{
  public static readonly Field<string> Title = new Field<string>( "Title", "Title", "An Example" );
  // ... and so on  
}

Somewhere in your application, you are basing the flow of your logic on whether the internal name of a field matched the Title field:

string internalName = "Title";
if ( internalName == FieldsList.Title )
{
  // ...
}

However, this will not compile with the error: Operator ‘==’ cannot be applied to operands of type ’string’ and ‘ExampleApp.Field‘. A solution would be to change the code as follows:

if ( internalName == FieldsList.Title.ToString() )

But that’s pretty ugly. Implicit type conversion to the rescue.

What we want is for the Field type to be able to behave as a string. Adding the following code to the Field class will do just that:

public static implicit operator string( Field<T> f )
{
  return f.InternalName;
}

What this tells the compiler is that “if there is a need to convert the type Field to string, use the InternalName property”. Now your code will compile.

The following code will also work:

Field<string> f = new Field<string>( "Title", "Title", "An Example" );
Console.WriteLine( f );

Something interesting happens when we use formatting strings. Let’s execute the following code:

Field<string> f = new Field<string>( "Title", "Title", "An Example" );
Console.WriteLine( "The title is: {0}", f );

This will not print ‘Title’ as you would expect. Instead, it outputs ‘ExampleApp.Field`1[System.String]‘. So in this case, we’ll need to override the ToString() method:

public override string ToString()
{
  return this; // Invokes implicit type conversion
}

Now everything works exactly as we’d expect it to.

Today I passed the 70-528 TS: Microsoft .NET Framework 2.0 – Web-Based Client Development exam. One more step towards my MCPD: Enterprise Application Developer certification :)

Recently I’ve been working a lot with the SharePoint standard templates. A client wanted us to build a Web Part that had the look and feel of a standard SharePoint Web Part and the easiest way to achieve that was using templates. Using these, we didn’t have to worry about custom fields, save buttons, validation and all the other goodness that SharePoint has to offer.

The project was progressing nicely. We inherited from some of the standard SharePoint controls to extend their behavior, like the Save button. Everything worked absolutely fine until we send the first version of the Web Part to our customer. Within a few hours a response came back; the Web Part did not work. Attached to the bug report was a screenshot with the “error message”: a NullReference exception. If there’s any exception I hate with all that is in me it is this one. It just doesn’t provide any information at all about what went wrong. Is it truly that hard to tell me just which object was null?

Anyway, it took us a while to figure out that the customer was using a Dutch language pack, and this was what was tripping up our Web Part. If he installed it on an English instance of SharePoint everything worked fine. Weird. We weren’t using any localization that was not part of the standard SharePoint template we had used as the basis of our work (for those interested, we used the UserListForm).

I will spare you the gory details of what we went through trying to figure out what was wrong. Eventually I simply started commenting out every control in our custom template one by one. If the error went away, I would have found the culprit. Crude, but it worked. The fault turned out to be in a single line of the template:

<SharePoint:CompositeField FieldName="Name" ControlMode="Display" runat="server" />

The why was just as elusive. The template used by the CompositeField didn’t lead us anywhere, nor did .NET Reflector’s help in looking at the source code. Again, we were mystified.

Until inspiration struck. Looking at the line of code I started wondering why there was a hard reference to a field called “Name” in there. Usually, these keys are put into resource files so a different language can use a localized version of the key. So I figured I’d give it a try. I changed “Name” to “Naam” (which is the Dutch translation). And lo behold! The Web Part worked in the Dutch instance of SharePoint and crashed gloriously in the English instance, giving us the exact same error. For kicks, we installed the French language pack and changed the key to “Nom”. Same result.

The solution to the problem was surprisingly easy. We changed the above line to:

<SharePoint:CompositeField FieldName="<%$Resources:wss,viewlsts_title%>" ControlMode="Display" runat="server" />

The choice of the viewlsts_title was somewhat arbitrary (you’d be surprised how many resource keys have the value “Name”) but it seemed the most appropriate. After this, the Web Part worked great in any language we threw at it.

I still don’t know if this is a bug in the SharePoint code or in the language packs, or anywhere else. I do hope that our explorations will spare you the same.

In his excellent post on How SharePoint 2007 Renders Its Content Geoff McElhanon shows how to programmatically load SharePoint-based templates. The code he shows us is as follows:

1
2
3
4
5
6
7
// Initialize template container with our custom template
templateContainer = new TemplateContainer();
templateContainer.Template = 
    SPControlTemplateManager.GetTemplateByName(RenderingTemplateId);
 
// Add the container to the webpart control hierarchy
Controls.Add(templateContainer);

However, I ran into a problem when I tried to load in a custom template of my own. The default location SharePoint searches in when you provide it with a template ID is C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES. My template was deployed in a subdirectory of this folder and although SharePoint is set to look in those as well, for some yet-to-be-defined reason it didn’t. So I needed an alternative. The solution is not rocket science but it did take me a while to figure it out:

1
2
3
4
5
6
7
8
// Initialize template container
templateContainer = new TemplateContainer();
Control ctl =
    (Control)Page.LoadControl( "~/_controltemplates/MyControlTemplates/MyControlTemplate.ascx" );
templateContainer.Template = ((RenderingTemplate)ctl.Controls[0]).Template;
 
// Add the container to the webpart control hierarchy
Controls.Add(templateContainer);

I hope this helps you out.

Last Thursday I passed the 70-541 MCTS: Microsoft Windows SharePoint Services 3.0: Application Development exam. So now I officially should know something about SharePoint development.

I have been advertising Ruby and IronRuby at my company for a while now — or trying too. We are a .NET solution provider and sofar they’re not convinced that Ruby will be worth the effort of learning. Oh well. One of these days I will come up with the decisive argument.

Thinking of that, maybe you can help out. What arguments would you use to have your company at least put some serious effort into exploring Ruby and/or IronRuby?

For completeness’ sake, IronRuby is Microsoft’s .NET implementation of the Ruby language. This means that we get all the dynamic language goodness of Ruby combined with the full range of .NET libraries available to C# (and any other .NET language) developers.

Justin Etheredge of CodeThinked has put together a set of tutorials geared specifically to help C# developers get up to speed with IronRuby quickly. If these don’t bring a great number of C# programmers to start experimenting with Ruby I don’t know what will.

The first two tutorials take you through setting up IronRuby and running a simple application:

And then the fun begins:

Justin is very actively adding new tutorials to the above list. The full series can be found here. I definately suggest subcribing to the RSS feed to keep updated.

It took a while, but the DevDays 2008 presentations are finally online. You can find them here:

DevDays 2008 Powerpoints