Of Code and Me

Somewhere to write down all the stuff I'm going to forget and then need

How to debug Play applications setup with the Typesafe stack from IntelliJ May 23, 2012

Filed under: IntelliJ,playframework,Web — Rupert Bates @ 8:18 pm
Tags: , ,

Set your sbt.bat to the following:

set SCRIPT_DIR=%~dp0
set SBT_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9999
java %SBT_OPTS% -Xmx512M -XX:MaxPermSize=256m -jar “%SCRIPT_DIR%sbt-launch.jar” %*

Run SBT in your project folder and then the ‘run’ command

In IntelliJ set up a run configuration (Run/Edit Configurations) as follows:

Add a new ‘Remote’ configuration
Give it a name
Set transport to ‘Socket’
Set debugger to ‘Attach’
Set host to localhost set port to 9999 (so it matches the port you set in SBT_OPTS in the sbt.bat file)

Put in some breakpoints and hit debug.


I’ll add in Linux/MacOs instructions next time I’m at a Linux box…


Getting Json.Net and Gson json libraries to play nicely with dates using ISO formatting January 28, 2011

Filed under: C#,Java,Web,WebServices — Rupert Bates @ 2:38 pm

I am working on something at the moment where I have a service written in .net which serves json created using the Json.Net library. This is then consumed by a client app written in Java which uses the Gson library to deserialize that json into Java classes. This was all working fine except for dates which caused parse errors in Gson.

The solution I am using is:

use ISO time format when serializing with Json.Net

    string json = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());    

When Deserializing with Gson set the date format as follows:

        GsonBuilder b = new GsonBuilder();
        Gson gson = b.create();
        gson.fromJson(json, MyObjectType.class);

Compile Aspx pages at compile time using the AspNetCompiler build task August 18, 2010

Filed under: Asp.Net,Web — Rupert Bates @ 1:20 pm

By default Asp.Net web applications don’t compile aspx files (only the code behind). This means that you can have errors in them which don’t appear until you actually hit the page.

To change this so that your aspx files get compiled along with all the rest of your code do the following:

  • Unload your web app (right click on the project and select ‘Unload Project’)
  • Open the csproj file in a text editor (right click on the project and select ‘Edit myProjectName.csproj’)
  • At the bottom of the file find the comment which says ‘To modify your build process…’ and insert the following after that comment:

<Target Name="AfterBuild">
<AspNetCompiler  VirtualPath="temp"  PhysicalPath="$(ProjectDir)" />


Change the Home Directory of an IIS 6 website using Powershell 2 and WMI August 3, 2010

Filed under: Powershell,Systems Administration,Web,Windows — Rupert Bates @ 4:13 pm

This function will set the home directory of an IIS 6 website using Powershell 2 (it will not work with v1).

You need to pass it the site description (from the Web Site tab in IIS), the new path and the server your website is running on (this can be a machine name or an IP address).

You wouldn’t believe how long it took me to get this working.

Function SetHomeDirectory($SiteDescription, $NewPath, $serverName)
 $query = "ServerComment = '" + $SiteDescription + "'"
 $webserver = Get-WMIObject -class IIsWebServerSetting -namespace "root\microsoftiisv2" -Filter $query -computer $serverName -authentication 6
 $nameQuery = "Name = '" + $webserver.Name + "/root'"
 $webdir = Get-WMIObject -class IIsWebVirtualDirSetting -namespace "root\microsoftiisv2" -Filter $nameQuery -computer $serverName -authentication 6
 $webdir.Path = $NewPath
 Set-WmiInstance -InputObject $webdir
SetHomeDirectory "mysite.co.uk" "d:\websites\mysite" "myServer"

Using Solr and Lucene with Asp.Net and Windows May 28, 2010

Filed under: Solr,Web — Rupert Bates @ 5:10 pm

Lucene and the Solr server layer which builds on it are probably the most widely used search technology on the internet today. And guardian.co.uk has recently adopted it as our main search technology and the platform on which our OpenPlatform is based. Because it is by the Apache foundation though I think there is a perception amongst .Net developers that it will be very difficult to use from .Net and will need to run on Linux; this is completely wrong. I have recently been working on incorporating it into an Asp.Net site which we have and it has been very easy indeed.

First step is to download Solr from here or you can also get “A comprehensive, tested version of Apache Solr based on the most recent stable Solr version with additional utilities, bug fixes and performance enhancements.” from Lucid Imagination. I just went with the standard Apache version.

You also need the Java runtime installed, preferably version 6.

Extract the zip file into a directory on your hard drive, go to that directory in a command prompt, then to the \examples directory and type java -jar start.jar. You should see the server start up and spit out a load of information, and that’s it! Up and running on Windows. Just to make sure, go to http://localhost:8983/solr/admin/ and you should see the Solr admin site.

The next thing to do is to work through the excellent tutorial here to get an idea of how Solr works. In my next post I’ll talk about defining schemas and connecting to Solr from .Net.


Setup Apache on Ubuntu April 8, 2010

Filed under: Linux,Systems Administration,Web — Rupert Bates @ 4:21 pm

Go to System -> Administration -> Synaptic Package Manager

Find the apache2 package (using the quick search is the easiest way), click ‘Mark for installation’ and then click the ‘Apply’ button

When the install is completed check that:

  1. the Apache program files are in /etc/apache2/
  2. there is an index.html file in /var/www/ (this is the root of the default vhost)
  3. apache2 is running, the command: ps -A | grep apache2 should return at least 1 result
  4. browsing to http://localhost/index.html serves that file successfully (I needed to restart it after the install before I could browse to localhost)

To start, stop and restart Apache :
/etc/init.d/apache2 start
/etc/init.d/apache2 s
/etc/init.d/apache2 restart


Donut caching in asp.net mvc 2 with Html.Action

Filed under: Asp.Net,C#,MVC,Uncategorized,Web — Rupert Bates @ 11:22 am

[Update – ok, so this officially doesn’t work, which sucks. I’m having a look at alternatives, but at the moment it looks like that is going to be reverting to MVC 1.0]

To do donut caching in Asp.Net Mvc 1.0 required quite a bit of hacking (or at least that was the only way I could get it to work), but with version 2 things get much better because of the addition of the Html.Action method.

As a quick recap, ‘donut caching’ is when you cache the whole of a web page except for small parts within it – the holes in the donut. A classic use for it is pages which have some personalised aspect like a logged in user name but are otherwise identical for all users.

To solve exactly this scenario I used the following code:

A child action called LoggedInUserInfo in my HomeController

        public ActionResult LoggedInUserInfo(HttpContextBase context)
            return View(context);

with a view of the same name:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HttpContextBase>" %>
<%@ Import Namespace="KableDirect.Service" %>
<%@ Import Namespace="KableDirect.Web.FrontEnd.Models.Shared"%>

        <li>You are logged in as <%= Model.User.Identity.Name %> </li>

        <li><%=Html.ActionLink("My Profile", "Profile", "Account")%></li>

        <%if (Model.User.IsAdmin()){%>
        <li><a href="<%= RouteHelper.GetAdminUrl(Model)%>">Admin</a></li>
        <li><%=Html.ActionLink("Logout", "Logoff", "Account")%></li>

I also have the following HtmlHelper method to make calling the asp.net WriteSubstitution() method easier:

    public delegate string MvcCacheCallback(HttpContextBase context);
    public static class CacheHelper
        public static object Substitute(this HtmlHelper html, MvcCacheCallback cb)
            html.ViewContext.HttpContext.Response.WriteSubstitution(c => cb(new HttpContextWrapper(c)));
            return null;

Now I can call my child action within my MasterPage using Html.Action as follows:

<%=  Html.Substitute(context => Html.Action("LoggedInUserInfo", "Home", new {context}).ToString()) %>

It is important that your action takes the context as a parameter or it will only be called once the first time the page is hit and then get cached along with everything else.
It is also important that you have a route in your route table that will catch the {controller}/{action} url pattern. See this post for more details.

Phill Haack now has a warning on his site about problems with donut caching in Asp.Net Mvc 2, but this has worked fine for me, I’ll update here if I find scenarios where this doesn’t work.

There is a good introduction to Html.Action here.


Error: No route in the route table matches the supplied values when using Html.Action or Html.RenderAction in Asp.Net MVC April 6, 2010

Filed under: Asp.Net,Error,Web — Rupert Bates @ 4:20 pm

I ran across this error today when using the new Html.Action:

System.InvalidOperationException: No route in the route table matches the supplied values.

It turns out that Action and RenderAction require there to be a default route to catch the {controller}/{action} pattern.

So adding this into the RegisterRoutes method fixed the problem:

                    controller = "Home",
                    action = "Index"

Format a string in RFC 2822 format for use with Http headers in c# March 17, 2010

Filed under: Asp.Net,C#,Coding,Web — Rupert Bates @ 11:45 am
var lastModified = AppStart.ToString("ddd, dd MMM yyyy hh:mm:ss ") + "GMT"; //note the hard coded GMT, there doesn't seem to be any other way to get this

Custom Date and Time Format Strings on MSDN
Standard Date and Time Format Strings on MSDN


301 redirects from Asp.Net February 9, 2010

Filed under: Asp.Net,guardian.co.uk,Uncategorized,Web — Rupert Bates @ 2:29 pm

Using Response.Redirect in Asp.Net will issue a 302 (temporary redirect) response. For items that have moved permanently you should issue a 301 (permanent redirect) using code such as:

<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
    Response.StatusCode = (int) HttpStatusCode.MovedPermanently;
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", "http://www.my-redirect.co.uk/newhomepage.aspx");

Paul Roach the SEO lead at guardian.co.uk explains why this matters:
“301 redirects are preferable from an SEO point of view because they instruct the search engine to pass all of the value of the original page to the destination page, including link equity and page history / age. If you use 302 redirects the search engine considers it a temporary state and does not pass the value from the original page to the destination page, this can also lead to both pages being displayed in the index.”