Random Thoughts of a Scatterbrain.
 Friday, March 07, 2008

WSS And DateTime Error

3/7/2008 12:16:40 PM (Eastern Standard Time, UTC-05:00)
In working with the SharePoint web services, I've noticed consistent errors with a few of the services which tend to return the following string:
String was not recognized as a valid DateTime
I hadn't been able to figure out what exactly the error was until today.

It's actually not related to a date/time string at all, but rather, the root of the error is in the service implementation itself.  The actual underlying error is an error indicating that a field value is no longer valid.  For example, if the item had a field referring to a lookup list, changes in the target list may invalidate a value on a given item.  Instead of returning a useful error, the web service returns the error above.

You may find this error when using the lists.asmx service or the dspsts.asmx service.

I "fixed" this by removing the offending field from the content type and also from the list and voila, no more errors.

It's hard to track down because the SharePoint itself will render the properties without any error indication in the view and edit properties view, but it will fail the entire request if one field is invalid and return a useless SOAP error.

 Monday, February 25, 2008

SharePoint Layout Pages With CodeBehind And Prototype

2/25/2008 8:11:26 PM (Eastern Standard Time, UTC-05:00)

Let it be known that I hate out of the box ASP.NET.  Hate it, hate it, hate it, hate it.  I detest it.  The simplicity with which it allows the average developer to create applications leads to applications designed for RAD and not for scalability and it does not encourage good decoupling of business logic from UI logic.  Certainly, there are a number of frameworks which aim to alleviate this (the Web Client Software Factory, for example), but I like to take it to another level all together.

Some would argue that I take the separation of UI and application logic to the extreme: my preferred methodology relies almost purely on client side scripts to render UI and using only web services to supply data using ASP.NET AJAX.  Certainly, I lose design time support, but I gain in pure speed (all of the UI logic is in Javascript files which are cached by the client), data transfer sizes (since the only traffic is data, no presentation whatsoever), and the ultimate decoupling of UI development and server component development (the UI developer only needs to know the data model exposed by the web services).

The way I look at it, you'll only write the code a few times, but it could be in use for months (and if you're lucky in this Web 2.0 age, even a year or two).  Sure, you lose some productivity for a single developer with the loss of design time support, but you gain tremendously over time with each request serviced in terms of performance and bytes saved (a particularly important point for high traffic/high data volume applications).  As a bonus, I find it generally easier to think about application design in these terms.

Admittedly, this model seems to work better for "business applications" as opposed to "content applications".

In any case, I was interested to see if this methodology could be applied to SharePoint development as I've been working with SharePoint for quite a while now, but not at the UI level.  SharePoint allows you to deploy "application pages" which can be seemlessly integrated (kind of) into a SharePoint deployment.  This seemed like the perfect starting point to try to integrate ASP.NET AJAX and prototype, one of my favorite Javascript libraries.

The general steps are:

  1. Create an ASP.NET AJAX web application
    1. Add a reference to the Microsoft.SharePoint assembly
    2. Add the prototype.js script file to the project
    3. Add a strong name key file and sign the project
    4. Build a simple page
    5. Create a simple service
  2. Copy the content files (.js, .aspx, .asmx) over to the server to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\ into a new directory.
  3. Test by visiting the URL: http://myserver/_layouts/mynewdirectory/default.aspx

The base page should be simple.  Use the default page created by the ASP.NET AJAX web application project template and change the base class for the _Default.aspx.cs file to LayoutsPageBase instead of of the default of Page.  If you're not using ReSharper ;-), you'll need to add a using statement to your file:

using System;
using Microsoft.SharePoint.WebControls;

namespace WssAjaxApplicationTest {
    public partial class _Default : LayoutsPageBase {
        protected void Page_Load(
            object sender, EventArgs e) {}
    }
}

Next, you will need to modify the Default.aspx file.  The gist of the modifications comes from an MSDN article by Ted Pattison:

<%@ Page Language="C#" 
    AutoEventWireup="true" 
    CodeBehind="Default.aspx.cs" 
    Inherits="WssAjaxApplicationTest._Default" 
    MasterPageFile="~/_layouts/application.master"%>

<asp:Content ID="Main" runat="server" ContentPlaceHolderID="PlaceHolderMain">
    <script type="text/javascript" src="_scr/prototype.js"></script>
    <script type="text/javascript" src="_scr/WssAjaxApplication.js"></script>
    <script type="text/javascript"> 
        var application;
           
        function Init() {
            application = new WssAjaxApplication();
        }
        
        Event.observe(window, "load", Init, false);
    </script>
    <asp:ScriptManager ID="ScriptManager1" runat="server" >
        <Services>
            <asp:ServiceReference Path="~/Services/EchoService.asmx" />
        </Services>
    </asp:ScriptManager>    
    <div>
        <input type="text" id="message-input" />
        <input type="button" id="action-button" value="Go!" />
        <br />
        <div id="message-output"></div>        
    </div>                
</asp:Content>

<asp:Content ID="PageTitle" 
    runat="server" 
    contentplaceholderid="PlaceHolderPageTitle" >
    Echo Page
</asp:Content>

<asp:Content ID="PageTitleInTitleArea" 
    runat="server" 
    contentplaceholderid="PlaceHolderPageTitleInTitleArea" >
    The Echo Page Test
</asp:Content>

I've bolded the key part above, which is linking to the master page for SharePoint layout application pages.  In addition, you can see that I've created three placeholder content sections with the key section being the PlaceHolderMain.  I've placed my Javascript references and my ScriptManager into this section, pointing to our simple service, EchoService.asmx.  Notice the use of the root squiggly "~" :-D and the lack of squiggly on the script references to prototype.js and WssAjaxApplication.js.

The service I'm going to be using for this demo is a simple "echo service" which just echoes the input string with the server timestamp attached.  The following is my simple implementation of this web service:

using System;
using System.ComponentModel;
using System.Web.Script.Services;
using System.Web.Services;

namespace WssAjaxApplicationTest.Services {
    /// <summary>
    /// Summary description for EchoService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    [ScriptService]
    public class EchoService : WebService {
        [WebMethod]
        [ScriptMethod]
        public string Echo(string message) {
            message = string.Format("You said: \"{0}\" at {1}", 
                message, DateTime.Now);

            return message;
        }
    }
}

As you can see by the .aspx page above, I've organized my service in a sub-folder called "Services".  Now just make sure that you've added a copy of prototype.js under the _scr directory and my application script:

WssAjaxApplication = Class.create();

Object.extend(WssAjaxApplication.prototype, {
    initialize:function() {
        this.MessageInput = $("message-input");
        this.ActionButton = $("action-button");
        this.MessageOutput = $("message-output");
        
        Event.observe($('action-button'), "click", 
            this.OnClickActionButton.bindAsEventListener(this), false);
    },
    
    OnClickActionButton:function(e) {
        if(e) { Event.stop(e); } // Stop the event       
        
        // Perform the echo.
        WssAjaxApplicationTest.Services.EchoService.Echo(
            this.MessageInput.value,
            this.OnClickActionButtonSuccess.bindAsEventListener(this),
            this.OnClickActionButtonError.bindAsEventListener(this)
        );          
    },
    
    OnClickActionButtonSuccess:function(result) {
        this.MessageOutput.innerHTML = result;
    },
    
    OnClickActionButtonError:function(error, userContext, methodName) {
        window.alert(methodName + 
            " failed with the message: " + error.get_message());
    }
});

The script simply attachs an event listener to the "Go" button and handles the click event.  Notice how clean and simple the HTML portion of the page is and how clean the Javascript is as well (admittedly, this is a very simple example).  The client rendering is completely decoupled from the UI logic except for the data and operations contract. 

You should be good to go so far as code goes.  Now compile your project with a strong named key file. 

Hopefully, the project was compiled successfully.  The next step is to copy the output dll to the GAC of the SharePoint server.  Be sure to note the public key token value.

This is probably the trickiest part: now you need to carefully merge the configuration files (is there a better tool to do this with?) generated by the project template with the web.config file located at the virtual directory root of your SharePoint application.  For example, if you have an application deployed at port 8080, the web.config file should be located at C:\Inetpub\wwwroot\wss\VirtualDirectories\8080.  Be sure to save a backup copy of the configuration file first before you attempt to merge it!

Once merged, you will need to add one more element to the configuration file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration> 
    <system.web>    
        <compilation batch="false" debug="false">
            <assemblies>
                <add assembly="Microsoft.SharePoint, 
                    Version=12.0.0.0, Culture=neutral, 
                    PublicKeyToken=71e9bce111e9429c" />
                <add assembly="System.Web.Extensions, 
                    Version=1.0.61025.0, Culture=neutral, 
                    PublicKeyToken=31bf3856ad364e35"/>
                <add assembly="WssAjaxApplicationTest,
                    Version=1.0.0.0, Culture=neutral, 
                    PublicKeyToken=97d3f1fd9f5212b9"/>            
            </assemblies>
        </compilation>
    </system.web>
</configuration>

I've highlighted the key line (the line above it should have been merged into the file previously).  The bolded entry above is for the web application binary.

To test whether you've succeeded, you can simply point your browser to the URL: http://myserver/_layouts/mywebapp/default.aspx and you will have a fully AJAX enabled application using ASP.NET AJAX to connect to a .NET web service with prototype as a general purpose Javascript utility library (and you can even add scriptaculous on top of that for more awesome).

I've included a self extracting 7z file of the solution (see link below) if you'd like a quick start.  Note that the Microsoft SharePoint binaries are not included and you will have to add them back manually before the project will build.

Happy coding!

WssAjaxApplicationTest.exe (162.02 KB)
 Sunday, January 13, 2008

Confucius On Programming

1/13/2008 4:18:02 PM (Eastern Standard Time, UTC-05:00)

One of the favorite classes that I took in college was an introductory course to Chinese philosophy. 

From time to time, I found one or two passages from The Analects that I could apply to my computer science major.

One of my favorites is passage 13:3:

Tzu-lu said, "The ruler of Wei is waiting for you to serve in his administration.  What will be your first measure?"  Confucius said, "It will certainly be the rectification of names."  Tzu-lu said, "Is that so?  You are wide of the mark.  Why should there be such a rectification?"  Confucius said, "Yu! How uncultivated you are!  With regard to what he does not know, the superior man should maintain an attitude of reserve.  If names are not rectified, then language will not be in accord with truth, then things cannot be accomplished.  If things cannot be accomplished, then ceremonies and music will not flourish...."

"Therefore, the superior man will give only names that can be described in speech and say only what can be carried out in practice."

To me, this applies to software engineering in the naming of classes, methods, properties, variables, and so on.  As McConnell writes in Code Complete,

The smaller part of the job of programming is writing a program so that the computer can read it; the larger part is writing it so that other humans can read it.  let [the reader] use their brain cells to understand the larger question of how your code works rather than the syntactic details of a specific expression.  You write readable code because it helps other people to read your code.

Indeed, sensible naming is a big part of this idea of legibility.  What I dig about Visual Studio 2008 is that the installed documentation includes excerpts from Framework Design Guidelines by Cwalina and Abrams which aims to include some of the key naming and design best practices into the core literature on the .NET Framework.  It's a necessary and needed move to help forward the education of the legion of .NET developers who continue to perpetrate terrible naming practices carried over from VB.

I mean seriously: if I have to read one more method name as a noun (or a property as a verb or a class as a verb), I'll just have to start researching a way to let me reach across the Internet and punch someone in the face -- nothing ruins my morning quite like finding a new class in source control named as a verb.  I'm also midly irritated when developers choose unconventional names for object types.  For example, the use of "Checker" as opposed to "Validator" -- ugh!

Admittedly, some artifacts are just really hard to name.  But in such cases, proper naming is probably even more important since if it's hard for the writer of the code to come up with a proper name, the wrong name will make the artifact even harder to understand for secondary readers.  There have been times where I've spent days trying to come up with a suitable name for a class (I'll name it, but I'll continue to mull it over through restless nights (true story) and refactor it once I do come up with a suitable name) since the last thing I want to do is to give something a cryptic, hard to understand name.

One of the easiest ways around this is to spend some time digging around the SDK and look for similar patterns in naming and see how the .NET framework designers structured their class and member names.  I also think that Cwalina and Abrams' Framework Design Guideline is a stalwart component of any .NET developer's library.

So the next time you're about to write a class name or create a new member, just remember,  "If names are not rectified, then language will not be in accord with truth, then things cannot be accomplished.  If things cannot be accomplished, then ceremonies and music will not flourish". I mean, who doesn't want their project to end with ceremonies and music :-D

 Tuesday, October 09, 2007

How Did I Miss This?!?

10/9/2007 7:34:55 PM (Eastern Daylight Time, UTC-04:00)

With the release of .NET 3.5 and Visual Studio 2008, Microsoft will also release selected bits of the .NET Framework source code!  With comments intact no less!kermitdancing_4.gif

To me, this is good news; very good news I mean, there are a variety of reasons, but mostly because I know that most people don't have the time, motivation, or energy to work through a book like Framework Design Guidelines.

My hope is that the Microsoft team, in doing so, will spur a movement within development teams to adopt better programming standards which are more aligned with the Base Class Libraries in naming, design, and architecture.  It should, hopefully, serve as a model to how things should be done in the post VBScript/VB6 days.

I just cringe sometimes when I dig into our codebase and find crazy things like methods not named as verb phrases, partial classes because a single file was getting too big (total abuse of partial classes instead of considering an object oriented approach to break down a large class), weird class names, catch blocks which have no code, and so on.

So for me, this is certainly good news and I hope to continue to form better practices as I get the opportunity to dive into the code.

 Thursday, October 04, 2007

Serializing Inheritance Chains With WCF

10/4/2007 1:42:26 PM (Eastern Daylight Time, UTC-04:00)

During a recent code review, I noticed that a colleague was sending me service entities from his WCF service with flags for the data type.  This itself wasn't so bothersome to me, but what did bother me was that the model he was sending back was violating one of the basic rules of object oriented programming: encapsulation (well, inheritence and abstraction, too) by mashing all of the data types into one type differentiated by a property.

Having worked extensively with XML serializers and XSD.exe generated code, I suggested that instead of mashing all of the objects into one definition -- with all of the different properties -- build one abstract definition and define a hierarchy of classes that inherit from the abstract class.

This worked out great since the family of objects all had a very obvious common base, but now the question turned to how to notify the runtime serialization engine to include the concrete types when returning abstract types from an operation.

I had imagined that the .NET 3.0 team would have made the process more "automagic" and use reflection to find inheriting classes instead of requiring the explicit declaration of inheriting classes.  As I soon found out, such is not the case as my proxy classes didn't include any of the inheriting classes; the proxy definition only contained the definition for the base class.

The answer is the KnownTypeAttribute which must be used to decorate the class definition of the base class (in my case, an abstract class).  One attribute must be added for each inheriting type which must be serialized across the wire.  For example:

[DataContract]
[KnownType(typeof(Invertebrates))]
[KnownType(typeof(Vertebrates))]
[KnownType(typeof(Mammal))]
[KnownType(typeof(Reptile))]
[KnownType(typeof(Human))]
public abstract class Animal {
	// Base class definition
}

Notice that the entire hierarchy has to be "flattened" and included in the declaration for the root base type. The DataMemberAttribute only has to be applied once on any property in the base class.

 Tuesday, August 21, 2007

Working With SQL Server Compact Edition 2005

8/21/2007 6:05:02 PM (Eastern Daylight Time, UTC-04:00)

One interesting issue that I just solved involved how to specify the location of the database file for a SQL Server Compact Edition 2005 connection string in a .Net add-in for Microsoft Office.

You see, when the add-in starts, it sets the context directory as the user's documents directory, which of course, makes it impossible to enter a configuration string for the data source of the connection string.

It works fine if the directory is hard coded - which is what I did for testing purposes initially, but of course, when I switched over to XP64, this broke as on XP64, the program is installed to "Program Files (x86)".

The solution lies buried in Microsoft's SQL CE documentation: there's a note that you should use a special token with the connection string like so:

<connectionStrings>
	<add name="ClientDatabase" 
		connectionString="Data Source=|DataDirectory|\data-file.sdf"
		providerName="Microsoft.SqlServerCe.Client" />
</connectionStrings>

The token needs to be included exactly as entered "|DataDirectory|". So how is this token replaced? In the static constructor of my Connect class that was autogenerated by Visual Studio, I added the following code:

/// <summary>
/// Initializes the logging subsystem for the <see cref="Connect"/> class.
/// </summary>
static Connect() {
	string path = Assembly.GetExecutingAssembly().Location;
	path = path.Substring(0, path.LastIndexOf('\\'));

	// Set the DataDirectory for the SQL Server CE connection string.
	AppDomain domain = AppDomain.CurrentDomain;
	domain.SetData("DataDirectory", path);
}
 Tuesday, August 14, 2007

Normalizing And Denormalizing SharePoint Field Names

8/14/2007 11:45:29 AM (Eastern Daylight Time, UTC-04:00)

Frequently, when working with Office, SharePoint, and SharePoint web services, it is necessary to convert between the "normalized" (hex escaped string) version of a field name.

To that end, I found a useful JavaScript tool for normalizing strings into SharePoint's "static name" format.

In .Net, we can simplify this using Regex and Uri.

    private static readonly Regex specialCharactersPattern
        = new Regex("[\\[*($%&)<>!?\\/\"{}\\s+-='@~`#\\\\:;^\\]]", 
            RegexOptions.Compiled);

    private static readonly Regex encodedCharactersPattern
        = new Regex("_x00(\\d{2})_", RegexOptions.Compiled);

    /// <summary>
    /// Normalizes the name of the SharePoint property name.
    /// </summary>
    /// <param name="key">The "human readable" key/property name.</param>
    /// <returns>
    /// The string with hex representation in place of special ASCII
    /// characters.
    /// </returns>
    private static string NormalizeSharePointPropertyName(string key) {
        return specialCharactersPattern.Replace(key, ReplaceSpecialCharacter);
    }

    /// <summary>
    /// Custom match evaluator to replace special characters within the input
    /// string.
    /// </summary>
    /// <param name="match">The pattern match.</param>
    /// <returns>The formatted version of the string.</returns>
    private static string ReplaceSpecialCharacter(Match match) {
        string replacement = string.Format("_x00{0}_",
            Uri.HexEscape(match.Value[0]).TrimStart('%'));

        return replacement;
    }

    /// <summary>
    /// Denormalizes the name of the SharePoint property.
    /// </summary>
    /// <param name="key">The normalized key/property name (static name).</param>
    /// <returns>
    /// The denormalized form of the input string ("human readable"
    /// with hex patterns replaced).
    /// </returns>
    private static string DenormalizeSharePointPropertyName(string key) {
        return encodedCharactersPattern.Replace(key, DecodeSpecialCharacter);
    }

    /// <summary>
    /// Custom match evaluator to replace the hex characters with special characters.
    /// </summary>
    /// <param name="match">The pattern match.</param>
    /// <returns>The ASCII format of the special character encoded in hex.</returns>
    private static string DecodeSpecialCharacter(Match match) {
        int start = 0;

        string replacement =
            Convert.ToString(
                Uri.HexUnescape(Convert.ToString(match.Value[0]), ref start)
            );

        return replacement;
    }

Download the sample console project to test it out.

SharePointNormalizationConsole.zip (4.35 KB)

 Tuesday, July 17, 2007

Tuesday Morning Thoughts

7/17/2007 10:50:01 AM (Eastern Daylight Time, UTC-04:00)

Some random stuff and some not so random stuff.

First, the Oral-B CrossAction Vitalizer is possibly the best damn (non-electric) toothbrush ever made.  It's comfy on the gums, it gets to the back teeth, and the handle is just right for control of pressure and angle.  The "soft" bristle isn't very soft at all, but I've found that it doesn't cause any pain or damage to my gums...it's just right.

Second, in reorganizing some of our code, I jumped headfirst into Microsoft's Smart Client Software Factory (SCSF).  While the verdict is far from conclusive, I have to say: I like it.  It implements several ideas I was tossing around in my head for a Windows Forms client but is obviously much, much more well developed and thought out.

I do find it annoying that it is somewhat difficult to visualize the relationships.  That is the one advantage to using an XML based object configuration system as opposed to the attribute based system used by the Composite Application UI Block that SCSF is built on: it's quite easy to wrap your head around the relationships and see how the pieces fit simply by reading the XML.  To be honest, it wouldn't be too terribly difficult to build similar (but certainly much less refined, given the amount of time I have) facilities with Spring utilizing the dependency injection, loosely coupled events, expression evaluation, and other components of Spring.

However, I think that the entire package, including the GAX pieces make this too compelling of a package to pass up.  There is surely a huge learning curve for the framework and library itself, but I think it will be made up for with the gain in development and deployment speed.

It's kind of cool that it also supports WPF modules.  I spent quite some time last night (up until 2 AM) trying to replicate some of the existing UI components that we have into WPF UIs.  I think I'm starting to "get it".  Not in the sense of why XAML is great for UI developers (I've always preferred declarative markup), but in the sense that I've kind of aligned myself with some of principles of XAML (i.e. layout, grids/tables, applying styles, backgrounds, etc. - which are of course slightly different than HTML) and I can now really appreciate how much easier it will be to create snazzy UIs in the future.

cab-hosted-wpf-UI.jpg

While I have Expresison Blend, I found it much more constructive to actually go into the raw XAML and write it by hand (well, not to mention that I find the UI hideous and unusable or perhaps I'm just way too Adobe-ized).  It was quite slow going at first, but once it clicked, it picked up very quickly.

Ultimately, however, I don't think that I can use WPF for our next release.  There seems to be some runtime instability with the current Visual Studio 2005 extensions (the November 2006 CTPs) to support WPF and WCF...I was only able to run my application once last night; subsequently, it would crash immediately.  The problem was only fixed by rebooting my machine.

But in any case, there are some great SCSF resources out there.  I would start from Cabpedia.com as CAB itself is really what presents the challenge in the Smart Client.  Cabpedia has a list of great resources which helped me at least grasp some of the conceptual ideas behind CAB.  In particular, a series of articles by Szymon Kobalczyk.

 Friday, July 06, 2007

WCF Configuration Intellisense

7/6/2007 4:06:38 PM (Eastern Daylight Time, UTC-04:00)

Hmm...I thought it was kind of odd that Visual Studio didn't support intellisense for WCF configuration elements (but then again, I've kind of become intimately familiar with the core elements without having the schema).

Turns out that you have to take care of it manually by updating the schema file for configuration.

Blogger Govind has a post with the necessary file and instructions.

Helps configuration go much more smoothly until Orcas arrives.

I'm surprised that this hasn't been posted across more blogs since it seems like a big, big bonus to have this for developing WCF applications.  Is it common knowledge?  Was there an SP that updated the schema files?  I know that installing .Net 3.0 didn't change the configuration files on my system at least.

 Tuesday, July 03, 2007

Enterprise Library vs. Log4Net

7/3/2007 5:35:18 PM (Eastern Daylight Time, UTC-04:00)

If there's one thing that really irks me is allegiance for the sake of allegiance.

Don't get me wrong, I have nothing against Microsoft Enterprise Library and in fact, in absense of any better alternatives, EL is indeed the best option for a whole slew of development tasks and better than rolling one's own solution.  But of course, the question is then: are there better alternatives.

Take logging for example.  There has been a movement in our team to use EL instead of log4net.  In all honesty, it's not a battle that I want to wage...it's simply not worth it for logging, but I think that for anyone considering one or the other, some serious evaluation is in order.  EL logging simply cannot hold a candle to log4net.

As I commented on James Newton Kings' blog:

James,

About 2 years ago, I started to seriously integrate logging into my applications.  During that time, I went through several rounds of testing both log4net and EL and I am currently in a discussion with other developers in my group on whether we should use the best available tool (log4net 1.2.11) or the do it the Microsoft way (EL 3.0/3.1).

In my opinion, the lack of hierarchical loggers is a significant weakness of EL as it requires much more thought and planning to make sure that you can isolate components down the line.  While flexibility is good, I think that having the free form category, priority ID, and event ID make it far more confusing than it has to be...18 overloads?  Do you expect people to remember or use the right category every time?  What about misspellings?  Of course, one could always write a layer to abstract these weaknesses of EL such as add a layer to translate Log.Debug() to some internal EL call, but then you have to ask if you've gained anything in the process.

Aside from this, I'm not sure if you are aware, but log4net utilizes buffered appenders for certain classes of appenders with the ADO.Net appender being one of those.  What does this mean?  I think you will see significant performance increases with buffered appenders (say buffer 250 messages in one flush versus making 250 individual inserts).

In addition, the procedures that are used by EL (although they can certainly be modified) add overhead out of the box.  For example, if WriteLog is called it *always* makes a second call to AddCategory, regardless of whether the category exists).  This is a round trip call from SQL Server to the calling client since there are no triggers on insert to the Log table and there is no call to AddCategory from WriteLog.  In addition, in the scenario that you end up with a category name that isn't in the log (yet another lookup), *another* lookup and insert is performed via InsertCategoryLog.  Since there are FK constraints on the tables, each insert also incurs an additional lookup behind the scenes to validate the foreign key.

Aside from this, I've found that log4net tends to fail gracefully whereas EL...not so much.  For example, if you try to use logging, but fail to include the correct configuration, the exception will bubble up to your application.  On the other hand, log4net will always trap the exception and not let it bubble up to your application and thus not raising an error where you would not expect.  Sure, you could put try-catch around all of your logging statements if you're using EL...but then, you have to ask yourself WHY?

I also forgot to mention that log4net, out of the box, allows loading of configuration files from any XML string (in application code without recompile of the source code).  This means that if one were so inclined, logging configuration would be stored on a central server, downloaded, and loaded on the fly.  If one were so inclined, it could be stored as embedded content with the assembly.  This flexibility allows for a great variety of design scenarios out of the box.

James also has two incorrect interpretations of the facts:

  1. log4net is not being developed actively.  Indeed, there was a looong period of inactivity on the realease side while the log4net project was going through integration with the Apache Software Foundation, but during that whole time, the mailing lists were active and so were the developers in helping users, answering questions, and certainly making todo lists for the release after incubation.  I would also offer the opinion that log4net should have less releases as it is the more mature, tested, and stable of the two libraries.
  2. EL is somehow more extensible than log4net.  This simply insn't true as both provide the source and both provide extensive SDK documentation, samples, and examples.

Commentor Smitha Mangalore also raises an interesting point: log4net supports logging across more platforms than does EL at this point (not to mention supporting more database targets out of the box than EL).

Just my take.  I think both have their place.  For application event logging and tracing, nothing beats log4net in terms of performance, ease of use, ease of configuration (yes, I find the configuration to be much more concise and understandable with log4net), and overall usability.

Update

So my interest was piqued: this whole discussion made me want to check the performance difference for myself.

So here are the test conditions:

  1. Machine:
    1. CPU: E6400 Core 2 Duo (2.13GHz @ 3.2GHz),
    2. Memory 4 GB RAM,
    3. Disk 1: 36GB @ 10,000 RPM
    4. Disk 2: 36GB @ 10,000 RPM
    5. Disk 3: 250GB @ 7200 RPM
    6. Disk 4: 74GB @ 10,000 RPM
  2. Test Scenario:
    1. The database will be dropped each before each test run.
    2. For EL, the default procedures and tables will be used.
    3. For log4net, the sample configuration and table definition will be used.
    4. A Stopwatch instance is created and started before the code enters a loop with 100,000 iterations.  The instance is stopped as soon as it exits the loop and the result is written to the console.
    5. For each pass, different sets of logging commands will be commented out (in retrospect, I should have used conditional compliation symbols).
    6. The only listener/appender is a database listener/appender.
  3. Results:
    1. EL: 138s
    2. log4net w/buffer = 1: 116s
    3. log4net w/buffer = 100: 78s
    4. log4net w/buffer = 250: 76s
    5. log4net w/buffer = 500: 78s
  4. Constant Work Time: 18s

So there you have it: with buffering enabled, log4net is up to nearly 2x as fast as EL.

 Thursday, May 31, 2007

SharePoint SoapServerException When Using Lists Service

5/31/2007 4:19:43 PM (Eastern Daylight Time, UTC-04:00)

When using the lists service to query the "User Information List" (the SharePoint list where the users and groups is located), you may encounter the exception:

System.Web.Services.Protocols.SoapException:
    Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException'
    was thrown.
  at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(
      SoapClientMessage message,
      WebResponse response,
      Stream responseStream,
      Boolean asyncCall)
  at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(
      String methodName,
      Object[] parameters)
  at ListsDataServiceSample.SharePoint.Lists.Lists.GetList(String listName) in
      F:\Projects\Sandbox\SharePointWebServicesSample\ListsDataServiceSample\
          Web References\SharePoint.Lists\Reference.cs:line 213
  at ListsDataServiceSample.Program.Run() in
      F:\Projects\Sandbox\SharePointWebServicesSample\ListsDataServiceSample\
          Program.cs:line 28

This error will occur if you are not using the "Administrator" account, which of course, is not always ideal, especially if you are writing a client side app.

The solution to fix this is to grant the account permissions on the "User Information List":

And then give the user "Read" permissions on the list:

 Wednesday, May 30, 2007

Correlation Across Workflow Instances

5/30/2007 3:15:58 PM (Eastern Daylight Time, UTC-04:00)

One of the problems that I've been working on solving recently centered around correlation in workflows.  In simple terms, where a workflow may produce parallel execution paths, correlation allows the runtime to route events to the right workflow execution path.

In every example that I came across on MSDN and online, the sample cases all assumed intra-workflow correlation as opposed to inter-workflow correlation involving "parent-child" workflow instances.

I posted the initial query - and the solution I used - on this subject over at the MSDN forums:

The trick, as it turns out, is that the CorrelationToken must be initialized in the parent workflow.  To accomplish this in the sample, I made a frivolous call to an InitializeCorrelation method on my service interface using a CallExternalMethodActivity, which was marked with the CorrelationInitializer attribute.  This activity executes right before the InvokeWorkflowActivity.


[Serializable]
public class WorkflowCommunicationServiceArgs : ExternalDataEventArgs {
private string key;

public string Key {
get { return key; }
set { key = value; }
}

public WorkflowCommunicationServiceArgs(Guid instanceId, string key)
:
base(instanceId) {
this.key = key;
}
}

[ExternalDataExchange]
[CorrelationParameter("key")]
public interface IWorkflowCommunicationService {
[CorrelationAlias("key", "e.Key")]
event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

[CorrelationInitializer]
void InitializeCorrelation(string key);

[CorrelationInitializer]
void OnChildCompleted(string key);
}

public class WorkflowCommunicationService : IWorkflowCommunicationService {
#region IWorkflowCommunicationService Members

public event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

public void InitializeCorrelation(string key) {
Console.Out.WriteLine("Key -> [{0}]", key);
}

public void OnChildCompleted(string key) {
MessageBox.Show(string.Format("Completed child; Key = [{0}]", key));

RaiseChildCompletedEvent(key);
}

public void RaiseChildCompletedEvent(string key) {
if (ChildCompleted != null) {
ChildCompleted(
null
,
new WorkflowCommunicationServiceArgs(
new
Guid("5D1667BF-61F6-4bf3-81C0-E70CBE15D2EF"),
key
)
);

}
}

#endregion
}

In essence, the idea is to have two correlation initializers: one utilized by the parent/outer workflow and one utilized by the child/inner workflow when signaling back to the parent.  It seems kind of counterintuitive to require two initializations...I'm still not sure how this is working under the covers, but it works :-)

The working example can be downloaded from: http://www.charliedigital.com/junk/CorrelationTest.Working.zip

 Friday, May 11, 2007

Office Add-In Development "Gotcha"

5/11/2007 4:07:18 PM (Eastern Daylight Time, UTC-04:00)

Because of the nature of how Office add-ins are loaded, it's an easy enough mistake to try to name your configuration file as:

<library-name-with-extension>.config or in my case, <executable-name-with-extension>.config.

In fact, the configuration file actually needs to be named WINWORD.exe.config and it should be located in the same location as the as the Word runtime.  It's kinda of baffling though, since as far as I understand, Word is not a native .Net application. 

Of course, I didn't notice this since the application was designed to run as a standalone executable and as an add-in, so the configuration file worked fine when launched as a standalone, but not so well when launched as an add-in.

 Thursday, April 19, 2007

Enterprise Library 3.0 Released

4/19/2007 2:25:04 PM (Eastern Daylight Time, UTC-04:00)

I just noticed moments ago that the final release of Enterprise Library 3.0 released recently.

Unfortunately, after a quick glance at the documentation, it seems like ObjectBuilder has been left off the table (link goes to online documentation for ObjectBuilder, which at the time of this post, is "under construction")...again.  I'm gonna have to dig a bit deeper and see if there's more info to be found.

 Sunday, March 25, 2007

Automatic Properties in C# 3.0...Why?

3/25/2007 3:09:52 AM (Eastern Daylight Time, UTC-04:00)

One of the new features in C# 3.0 makes absolutely no sense to me: automatic properties.

I have two issues with this approach. First, Wouldn't it make more sense to just have VS ask: "Do you want to generate a public property" when a user creates a field (like when VS detects the user adding an event handler)? From the description, it seems like the private field doesn't get generated until compile time, meaning the class writer is working against the public property as well. This seems odd since one of the main scenarios for using public properties and private fields is so that the class writer can manipulate the internal data representation without affecting the external interface. Scott himself mentions:

The benefit of this is that from a type-contract perspective, the class looks exactly like it did with our first (more verbose) implementation above. This means that -- unlike public fields -- I can in the future add validation logic within my property setter implementation without having to change any external component that references my class.

Which leads me to wonder why the developer would not just write the private field declaration and auto-generate the get/set methods instead, a much more logical approach to class design which leads to more legible code.

I can appreciate that it saves space in the code view by omitting otherwise "useless" lines, but don't code regions already accomplish the same thing?

Seems like a pretty useless feature to me that ultimately leads to more abstract code (less readable, in my opinion).

Aside from that, the code usage itself looks suprisingly similar to an abstract class.  From a design standpoint, if it's not clear what the validation logic or some other property masked logic is at the moment, if it's not clear how the internals of the class should function, wouldn't it make sense to program against an abstract class and put the actual logic into concrete classes at a later time when that logic is available?  It seems to me that what the automatic property is saying about the class is that: "I know what my external interface looks like, but I don't know what my internal representation and logic should be", which is one of the reasons we have abstract classes, right?  So that we can substitute the actual representation of the internal logic of the class at any time down the line while maintaining the external interface contract.  I dunno, just seems like a useless and otherwise bad feature to me.

One of the other main features, LINQ, already has me shuddering in anticipation of the nasty code that I'll inevitably have to face down the line.  Can you imagine the horror of code mixed with complex data queries in any application of significance?  For the same reasons that one would put a public property as a facade to a private field, it only makes sense to use a stored procedure, view, or table valued function as a facade to the underlying data (now I could see a case being made for it with a framework that allowed the queries to be loaded and cached dynamically at runtime from external files with a cache refresh callback on file change).

 Thursday, March 22, 2007

NHibernate Or Bust!

3/22/2007 5:23:35 PM (Eastern Daylight Time, UTC-04:00)

So my interest in NHibernate is picking back up again.  The 1.2 beta release that's circulating now (the candidate release has been out since February of this year) addresses various issues with NHibernate in my previous time with it.

Specifically, the biggest issue was native support for generic types.  In addition, it seems like there are various other goodies in the 1.2 release such as stored procedure support.

And to think, I just got the team to standardize on Microsoft Enterprise Library 3.0.  I'm wondering how to break this to the team.

I guess in a sense, they are not completely incompatible.  Roll your own queries and data access routines are still the way to go for more complex queries (does NHibernate handle FOR XML EXPLICIT?) and anywhere high performance is critical.

The beauty of this whole thing is that as NHibernate has gained traction since the first time I used it like 2 years ago, the tool support has evolved tremendously.  Combined with MyGeneration and user templates, I was up and running (although the generated output had some minor errors in the XML mapping file) in minutes.  Not only has the tool support improved, the documentation has improved as well.

There is still some conflict, internally, as I was just ragging on LINQ last week with another group of developers for the simple fact that it creates a tight coupling between code and the raw data.  Whereas with stored procedures, you can have dedicated DBAs write highly performant code and you can modify the underlying data retrieval and layout so long as you maintain the same resultset, with dynamic queries, you lose a lot of that flexibility.  In addition, you lose a bit of testability as well since many times, it's just really helpful to be able to test the SPROC independently of any code (or perhaps breakdown subqueries in the SPROC to test small subsets of data).

In actuality, I think that having the mappings as XML is probably better than using LINQ since the XML mapping files can be loaded at runtime, meaning that the deployed mappings can still be manually updated whereas LINQ would necessitate a recompile of the source (my understanding of it).

So if you haven't checked out NHibernate for a while, now's a good time to get a refresher and re-evaluate the library.  I think it will still stick around even after LINQ is released.

 Tuesday, March 20, 2007

Combating Namespace Bloat With .Net XML Serialization

3/20/2007 10:37:00 AM (Eastern Daylight Time, UTC-04:00)

Anyone who has used the .Net XmlSerializers have surely encountered the dreaded namespace bloat which makes the serialized objects grow to ridiculous sizes.

There's a nice little article over at TopXML on how to deal with this bloat.

If you're using WSCF, on the client stub, I've gotten into the habit of writing custom serialization overrides in partial classes which ensure that if the client needs to serialize objects into XML, I'm doing so in an efficient manner.  It'd be nice to see it added to the server side class constructors as well.  Add your vote for this feature over at the WSCF dicussion boards.

 Wednesday, February 28, 2007

WF Passivation Services Issues

2/28/2007 6:16:29 PM (Eastern Standard Time, UTC-05:00)

If you're expecting the WF (Windows Workflow) passivation services to work out of the box, well, you're half right. 

From one of my workflows, I've been able to trap that an error was being thrown at some point during execution, but it wasn't clear what the actual error was or what was causing it.  I knew it had to do with passivation services since everything was just fine and dandy once I removed the passivation services from the equation.

From the runtime level, I received the following not-so-helpful error message:

System.InvalidOperationException: Workflow with id "[some-guid]" not found in state persistence store.

Just on a whim, I attached SQL Server Profiler to the database instance where the persistence store is attached to track the queries and lo-and-behold, the mystery culprit surfaced:

declare @p10 int
set @p10=0
declare @p11 uniqueidentifier
set @p11=NULL
exec InsertInstanceState @uidInstanceID='2686AB8F-35A4-49C3-AED8-9F239D00D3AC',@state=0x,@status=3,@unlocked=1,@blocked=0,@info=N'Type
''Zorch.Alta.EastCastle.Workflows.DataProviders.Implementation.MockStepProvider'' in Assembly ''Zorch.Alta.EastCastle.Workflows, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null'' is not marked as serializable. Type ''Zorch.Alta.EastCastle.Workflows.DataProviders.Implementation.MockStepProvider'' in
Assembly ''Zorch.Alta.EastCastle.Workflows, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'' is not marked as serializable.',@ownedUntil=''9999-12-31
23:59:59:997'',@ownerID=default,@nextTimer=''9999-12-31 23:59:59:997'',@result=@p10 output,@currentOwnerID=@p11 output
select @p10, @p11

Well, yeah, duh!  It seems so obvious after the fact.  So the moral of the story is to make sure that all of your classes are marked with serializable :P I'm just not sure why they decided to place the error message in the procedure call to insert the instance state.  Why not actually raise an error to the workflow runtime that a class was not serializable?

 Monday, February 19, 2007

Setting Links in Word Programmatically

2/19/2007 1:58:10 PM (Eastern Standard Time, UTC-05:00)

Since I didn't find anything on this topic via Google...

Just a quick "how to" on setting links in Microsoft Word programmatically (in this case, C#):

public void CheckRuntime() {
    object reference = null;

    try {
        reference = Marshal.GetActiveObject("Word.Application");
    }
    catch (COMException) {
        System.Console.Out.WriteLine("No instances found...");
    }

    if (reference != null) {
        try {
            System.Console.Out.WriteLine("Found running instance!");

            ApplicationClass wordRuntime = (ApplicationClass)reference;

            System.Text.StringBuilder buffer = new StringBuilder();
            foreach (Document document in wordRuntime.Documents) {
                buffer.AppendFormat("{0}|", document.Name);

                if (wordRuntime.Selection != null) {
                    System.Console.Out.WriteLine("Selected text: \"{0}\"",
                        wordRuntime.Selection.Text);

                    object optional = Missing.Value;
                    object url = "http://www.google.com/";

                    if(wordRuntime.Selection.Hyperlinks.Count == 0) {
                        wordRuntime.Selection.Hyperlinks._Add(
                            wordRuntime.Selection.Range,
                            ref url,
                            ref optional
                        );
                    }
                }
            }

            System.Console.Out.WriteLine(
                string.Format("Currently open documents are: {0}",
                buffer.ToString().Trim('|'))
            );
        }
        finally {
            Marshal.ReleaseComObject(reference);
        }
    }
}

The code is wrapped in a function call I'm using for testing. The key part of this is detecting the currently selected text and using the ApplicationClass.Selection and then invoking _Add. The method takes three parameters. Make sure that your first parameter is a Range class instance, your second parameter is passed by reference, and your third parameter (the SubAddress) is set to System.Reflection.Missing.Value.

This should set the text point to any input URL.

 Thursday, February 08, 2007

Revisiting Spring.Net

2/8/2007 11:25:51 AM (Eastern Standard Time, UTC-05:00)

Spring.Net is an application framework which has its roots in the Spring Framework for Java.

Now first of all, I know many developers have an averse reaction to the use of the phrase "application framework" and immediately reject such things without second consideration.  I always hear tales that begin like so: "Well, on this one project, we used an application framework and it ended up not doing anything exactly the way we wanted and we had to modify it anyways..."

Four thoughts on this:

  1. No two applications are exactly alike.  If that were so, we'd all be out of jobs as software engineers because it'd probably have already been done before.  As well, no two application frameworks are alike (although on some level, Spring is interchangeable with Castle).
  2. Spring, I have found, does not restrict me in anyway in terms of my solution design.  If anything, it frees me to use more flexible designs and allows me to create much cleaner and better designs.  Inversion of Control is your friend.
  3. Spring includes the source.  Dude, if it doesn't do exactly what you want it to, you are 100% free to modify and reuse it (and maybe even resubmit it to the project if it's well written and useful).
  4. The documentation and development team on Spring (and Castle to a lesser degree) are great.  The documentation is very thorough and well organized and the developers are constantly monitoring the discussion forums and reaching out to users.  Many times, with any sort of large library, you may be under the impression that it doesn't do something (thus leading you to believe that you have to write it anyways and believing that it was pointless to use the framework), but it may actually be the case that you simply haven't found the facilities in the library to accomplish your task.

On top of this, the support forums and developers working on the framework are great resources for hashing out design ideas (outside of one's normal circle of peers).

Yes, it's true, Spring requires the use of what can become massive XML configuration file(s).  Yes, it can be difficult for first timers to grasp inversion of control, understand what exactly it is that Spring offers, and in general, find anything in Spring that would significantly make one's life easier as a developer without a learning curve.  Yes, Spring is huge; it encapsulates a lot of "stuff" that can be confusing and seem like bloat one's first time encountering it (I myself only ever use a small subset of the features of Spring).

However, in the end, I think Spring brings so much to the table (too much for me to list here), it's hard to discount it without at least giving it a real evaluation.  For any sort of non-trivial application, Spring allows the designer to add much more flexibility and decrease the complexity of the codebase by encapsulating a lot of the dirty work.  (I would agree that there is a complexity cutoff where if your application sits below this cutoff, it's simply not worth it to include Spring in the discussion, as the time it takes to understand and find its usages in your scenario would not be worth it).

I've been using Spring for almost a year now and I simply can't imagine writing an application without it.  With the latest release, the introduction of the data access library, Spring becomes even more compelling by removing a lot of the boilerplate code that one would write when performing data access.  Admittedly, in a sense, it is a replacement of one set of boilderplate code for another, but it is a much more elegant design than using raw ADO or even Enterprise Library for that matter.  Spring introduces the usage of a delegate/callback pattern for "rendering" the returned data rows and sets into domain objects and sets.

I use the term rendering because this is the same exact pattern that I've been using with regards to the JavaScript that I've been writing for my AJAX enabled applications.  It's an elegant pattern that, in JavaScript, allows for decoupling of the code to retrieve that data from a web service and the code that renders the data.  In a sense, Spring does the same, except, instead of rendering a UI, it renders a domain object (or set) using the delegate, which decouples the data access plumbing from the building of the domain object.

Having used NHibernate previously, I have to say that in many cases, I still prefer performing my own data access code and domain object rendering as it allows me much more flexibility and control.  There is less processing overhead and not to mention (when I last checked) NHibernate still does not natively support generic types.

I've mostly been sticking with Enterprise Library, which is basically just a step above raw ADO, but I'm gonna give this a shot since it's yet another step or two above Enterprise Library.

On another note, it seems like Microsoft's Patterns and Practices Group is finally releasing the next version of Enterprise Library.  In a sense, EL is a "necessary evil".  As far as 2.0 goes, I cannot say that it does anything particularly better than other libraries that fill the same purpose as any given block, but what it does do is it encapsulates multiple functional spaces (logging, data access, exception handling, configuration) into one.  In addition, having the Microsoft Seal of Approval also helps with acceptance.  As an example, the rolling flat file trace listener has had a counter part in log4net since I've been using it (over 1.5 years now).  The data access application block, while it does clean up data access code, is still pretty close to raw ADO.Net usage patterns; in other words, it brings almost nothing to the table (almost; I still endorse it over raw ADO.Net to be sure).

It'll be interesting to see what this Object Policy Application Block actually does.  It seems like it's conceptually similar to Spring's IApplicationContext or Castle's Windsor Container.  I'm not one to latch onto a product simply because it's from Microsoft's P&PG, so I'm hoping they can actually bring something new to the table to make their library more compelling than Spring or Castle (both of which are much more mature by now and encapsulate a far greater set of features).

As for the any concern over the longevity of Spring and Castle, I feel pretty confident that what happened to NDoc, will not be happening to Spring or Castle.

 Friday, February 02, 2007

Most Annoying Error Ever.

2/2/2007 10:06:12 AM (Eastern Standard Time, UTC-05:00)

So I've been working on this Windows Forms app for the past month and recently, it started developing this very odd error that occurs only after a successful build, just as I fire up the window.  Behold:

Super annoying error that makes no sense...

Argh!  What's worse is that it pops up not once, not twice, but three times each time I show the form with that super annoying Windows XP "Critical Stop" sound clip each time.  BUT it only happens if I launch the form from VS! These things...they infuriate me because it's virtually impossible to track down.  Throw me a bone, Microsoft, at least tell me what line it's on (which brings me to another point: NullReferenceException - at least when deployed in debug mode, can't you guys just tell me what reference was null?).

I mean, it would be easy if it said something like "Unable to cast object of type 'X' to type 'Y'" - that would make perfect sense, duh! - but this is just baffling.  It's not like I'm getting complier errors either.  I dunno...I just can't figure out why it would only throw up this modal dialog only when I launch the app (without debugging) from VS.