A slight Nitpick/Improvement for Tekpubs Video about ASP.net MVC Routing

Tekpubs series about ASP.net MVC 2 is really useful and has tons and tons of great tips and code samples, and the episode about Routing (#12) is no exception. However, there is one thing I really didn’t like about it.

Around 30 Minutes in when discussing SEO Optimizations, they show a great tip how to enforce canonical URLs. Unfortunately, they do it by modifying the Response object directly. Basically the code looks like

// This snippet doesn't make much sense if you haven't
// watched the Episode, sorry.
public ViewResult Details(int id)
{
    //snipped some parts
    EnforceCanonicalUrl(jobAd.DetailsRouteValues());
    return View(jobAd);
}

private void EnforceCanonicalUrl(RouteValueDictionary routeValues)
{
    if(someCheckFails){
        Response.RedirectLocation = someLocation;
        Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
        Response.End();
    } 
}

This doesn’t follow the MVC pattern, and the speaker even acknowledges it in the video as it makes unit testing hard. The proper way is to return an ActionResult from the ControllerAction instead. As I happen to have already written a PermanentRedirectResult, my suggestion to improve this code is this:

public ActionResult Details(int id)
{
    //snipped some parts
    var enforcedResult = EnforceCanonicalUrl(jobAd.DetailsRouteValues());
    // As View and enforcedResult have different types, I cannot use the ?? operator
    if(enforcedResult != null) return enforcedResult;
    return View(jobAd);
}

private PermanentRedirectResult EnforceCanonicalUrl(RouteValueDictionary routeValues)
{
    if(someCheckFails){
        return new PermanentRedirectResult(canonicalPathAndQuery);
    } else {
       return null;
    }
}

So I changed the return type of the controller action to ActionResult instead of ViewResult, and I gave EnforceCanonicalUrl a return type. This function now either returns null or a PermanentRedirectResult, and the controller action now checks for it. There are of course more ways to refine it, but it is in line with the ASP.net MVC pattern of having Controller Actions return ActionResults instead of modifying the Response directly.

Project Server 2010 Beta: “Failed to provision site PWA with error”

I’ve installed Project Server 2010 Beta on my SharePoint 2010 Beta server and got this error when provisioning the PWA site:

Failed to provision site PWA with error: Microsoft.SharePoint.SPException: The template you have chosen is invalid or cannot be found. —> System.Runtime.InteropServices.COMException (0x81071E44): 0x81071e44The template you have chosen is invalid or cannot be found.
at Microsoft.SharePoint.Library.SPRequestInternalClass.ApplyWebTemplate(String bstrUrl, String bstrWebTemplateContent, String& bstrWebTemplate, Int32& plWebTemplateId)
at Microsoft.SharePoint.Library.SPRequest.ApplyWebTemplate(String bstrUrl, String bstrWebTemplateContent, String& bstrWebTemplate, Int32& plWebTemplateId)
— End of inner exception stack trace —
at Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx)
[…]

The solution turned out to be simple: Just wait. Seems like there is an additional Timer Job for provisioning site templates and stuff. No idea when it runs as I had a weekend between failure and success, but it works now.

TimeSpan.js Version 1.2 released

I’ve just pushed a new Version of my TimeSpan Library to GitHub. Version 1.2 contains a new “static” constructor TimeSpan.FromDates which takes two dates and returns the difference between them as a TimeSpan. If the second date is earlier than the first date, the TimeSpan will be negative. Pass true as third parameter to force it to be positive.

Usage example:

var date1 = new Date(2010, 3, 1, 10, 10, 5, 0);
var date2 = new Date(2010, 3, 1, 10, 10, 10, 0);
var ts = TimeSpan.FromDates(date2, date1);
var ts2 = TimeSpan.FromDates(date2, date1, true);
alert(ts.totalSeconds()); // -5, because we put the later date first
alert(ts2.totalSeconds()); // 5, because we passed true as third parameter

Running three Monitors off a Radeon 5870 card

Okay, as said last time, I bought a Radeon 5870 card with the desire to drive three monitors. Now, ATI proudly claims that they have three independent display controllers, which is true. And the card has 2x DVI, 1x HDMI and 1x Display Port, so you would expect a setup of 2x DVI and 1x HDMI to work, right?

Wrong. You see, DVI/HDMI and DisplayPort have different Signal Types. DVI and HDMI use TDMS, while Display Port uses a completely different protocol. And guess what? The card only supports up to two TDMS Signals, which means 1x DVI and 1x HDMI or 2x DVI, but not 2x DVI and 1x HDMI as that would require three TDMS outputs.

Now, the solution seems easy, just get one of those cheap $10 DisplayPort > HDMI or DVI adapters, right? Wrong again. Those adapters do not convert the signal, they seem only able to mechanically convert and then require the host to generate a TDMS Signal. You need an “active” Adapter, that is an adapter that actually converts the signal. Those require extra power, usually provided through an USB Port. And they are expensive.

I bought one from Dell (R478G), which set me back a hundred bucks. Other adapters are sold by Sapphire or Accell and possibly others, but they are all around that price range. Sadly, I already had three Monitors at that point, otherwise I would recommend paying the extra money for a DisplayPort Monitor as the Adapter can cause problems (check the reviews) or even considering a second graphics card, which kinda defeats the purpose of getting a Radeon 5xxx in the first place.

Oh well, at least I now finally have three monitors for a 6016 Pixel wide screen…