Computerworld article

Today Danish IT-magazine Computerworld published this interview with me. The article focuses on how to develop and maintain skills that are in demand.

Article

Running background tasks

Recently I had to implement a feature that ran some processing in the background at regular intervals.

There are many ways to implement this. Usually this could mean batch processing from a headless Windows task or in a Windows Service. However, in this particular case it had to be run on a shared webhost, so in-process from the application.

The background processing could take several minutes, and I wanted to make sure the background processing did not influence on the stability of the main priority i.e. serving HTTP requests. So running it off ASP.NET’s managed thread-pool was out of the question. Instead, I decided to spawn a single worker thread that could run all background tasks one item at a time. The thread would spend most of its time sleeping, and occasionally a timer would trigger it to check for due tasks.

It was crucial to prevent a daily task to run twice, when for instance the host would decide to restart the application pool. So the implementation should be able to wake up and tell when it is time for each job to run.

The implementation is modular and easily extensible. It only takes reference to the BCL assemblies, so you can use it for webbed as well as Windows applications. I included a simple file based persistence implementation.

Please have a look at the code on https://bitbucket.org/klinkby/timerjob
I have included a sample console app that should get you going in two winks of a pony’s tail.

If you want to use it in an ASP.NET application you would propably like to create a singleton instance of the JobManager in the Application_Start event, and dispose of it in the Application_End in Global.asax.

Workaround for Content-Disposition bug in ASP.NET, SharePoint

A simple HTTP Module that implements a workaround for a common bug in ASP.NET applications that prevents downloading of files with comma in the filename.

When a Chrome browser downloads a file that have a comma in its file name, according to the RFC6266 the file name must be enclosed in quotes. If not the browser simply prevents the download with the following message:

Chrome error messageDuplicate headers received from server
Error 349 (net::ERRRESPONSEHEADERSMULTIPLECONTENT_DISPOSITION): Multiple Content-Disposition headers received. This is disallowed to protect against HTTP response splitting attacks.

Very few applications does this right, and even SharePoint and Office 365 are affected by this bug.

On https://bitbucket.org/klinkby/workaround-for-content-disposition-bug-in-asp.net-sharepoint/ I have published a source and binaries for a simple HTTP module that plugs in to an existing application, examines responses, looking for those ill formatted filenames in content-disposition headers using an efficient regular expression. Those affected are corrected and returned to the client, thus allowing Chrome to download the files.

To use the module add the dll to the GAC or the bin folder, and register the module in the application’s web.config file in the system.webserver element:

<system.webServer>
 <modules runAllManagedModulesForAllRequests="true">
 <add name="cdf" type="Klinkby.Web.ContentDispositionFix.RemedyHttpModule, Klinkby.Web.ContentDispositionFix, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f97db8c3b9326f3e"/>
 </modules> 
</system.webServer>

Read more:

Editing a SP2010 ent. wiki page in IE9-standards mode

SharePoint 2010 is not compatible with IE9. The master page forces it in IE8 compatibility mode.

One of the odd quirks you will experience if you change the master page to IE9 mode is when editing an enterprise wiki page. When you press the ‘[‘ key, the cursor jumps to the end of the paragraph.

The code below will let SharePoint know that IE9 is just like any other browser and prevent this behavior.

if (RTE)
{
    // stop ie from moving caret to end of paragraph when typing a [ in ent wiki
    RTE.Cursor.updateRangeToCurrentSelectionWithOptions = function (b) {
        ULSNVe: ;
        RTE.Cursor.$41_0 = false;
        RTE.Cursor.$40_0 = false;
        RTE.Cursor.$4x_0();
        RTE.Cursor.$1I_0 = false;
        var c = RTE.Selection.getSelectionRange(), a = true;
        if (RTE.Canvas.$K && RTE.Canvas.$K.parentNode && RTE.Canvas.$K.parentNode.parentNode) a = RTE.Cursor.s_range.moveToNode(RTE.Canvas.$K);
        else if (!c) a = false;
        else a = RTE.Cursor.s_range.moveToRange(c);
        if (!a && !b) RTE.Cursor.s_range.clear();
        else if (a) {
            var d = RTE.Cursor.s_range.expandInNonEditableRegion();
            if (d) RTE.Canvas.$K = d;
            if (/*!RTE.RteUtility.isInternetExplorer()&&*/!RTE.Canvas.$K) {
                var e = RTE.Cursor.s_range.$1N();
                e.select()
            }
        }
        !b && RTE.Canvas.$F()
    };
};

Managing SharePoint feature state with PowerShell

This is a small function that wraps the Get-SPFeature, Enable-SPFeature and Disable-SPFeature to control state of farm, site or web scoped features.

I makes it a breeze to set the state of the built-in SharePoint features during a PowerShell deployment.

function EnsureFeatureState(
    [Parameter(Mandatory=$true, Position=0)]
    [string] $id, 

    [Parameter(Mandatory=$true, Position=1)]
    [bool] $enabled,

    [Parameter(Mandatory=$false, Position=2)]
    [string] $site)
{
    if (!$site)
    {
        [Microsoft.SharePoint.Administration.SPFeatureDefinition]$f = Get-SPFeature -Identity $id -Farm:$true -ErrorAction SilentlyContinue
        if ($f -and !$enabled)
        {
            Disable-SPFeature -Identity $id -Confirm:$false
        }
        if (!$f -and $enabled)
        {    
            Enable-SPFeature -Identity $id
        }
    }
    else
    {
        [Microsoft.SharePoint.Administration.SPFeatureDefinition]$f = Get-SPFeature -Identity $id -Site $site -ErrorAction SilentlyContinue
        if (!$f)
        {
            $f = Get-SPFeature -Identity $id -Web $site -ErrorAction SilentlyContinue
        }
        if ($f -and !$enabled)
        {
            Disable-SPFeature -Identity $id -Url $site -Confirm:$false
        }
        if (!$f -and $enabled)
        {    
            Enable-SPFeature -Identity $id -Url $site
        }
    }
}

Here is an example that enables two farm features.

# enable farm features
(
'319d8f70-eb3a-4b44-9c79-2087a87799d6', # Global Web Parts
'612d671e-f53d-4701-96da-c3a4ee00fdc5'  # Spell Checking
) | foreach-object { 
    EnsureFeatureState $_ $true
}
Follow

Get every new post delivered to your Inbox.