image

Yesterday I struggled with finding a way to encrypt a cookie without using Forms Authentication. The problem is that the FormsAuthentification.Encrypt method is using internal methods on the MachineKeySection class.

On the MachineKeySection class there are methods like EncryptOrDecryptData, HexStringToByteArray, ByteArrayToHexString that are all internal. Why make useful functions like these internal?? After some Googling I found this article on codeproject where Eric Newton has made a MachineKeyWrapper that through reflection uses the internal methods to encrypt/decrypt cookie data.

The code in the article does not run on .NET 2.0, you have to update the static constructor of MachineKeyWrapper to this:

static MachineKeyWrapper()
{
    MachineKeySection config = (MachineKeySection)ConfigurationManager.GetSection("system.web/machineKey");
    Type machineKeyType = config.GetType().Assembly.GetType("System.Web.Configuration.MachineKeySection");

    BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Static;

    Type[] typeArray = new Type[5];
    typeArray.SetValue(typeof(Boolean), 0);
    typeArray.SetValue(typeof(Byte[]), 1);
    typeArray.SetValue(typeof(Byte[]), 2);
    typeArray.SetValue(typeof(Int32), 3);
    typeArray.SetValue(typeof(Int32), 4);

    _encOrDecData = machineKeyType.GetMethod("EncryptOrDecryptData", bf, null, typeArray, null);
    _hexStringToByteArray = machineKeyType.GetMethod("HexStringToByteArray", bf);
    _byteArrayToHexString = machineKeyType.GetMethod("ByteArrayToHexString", bf);

    if (_encOrDecData == null || _hexStringToByteArray == null || _byteArrayToHexString == null)
    {
        throw new InvalidOperationException("Unable to get the methods to invoke.");
    }
}

It is really irritating when you have discovered a nice solution through Reflector only to find that the class or method that was being used is marked as internal. The .NET framework team is a little too liberal with the internal keyword :)

image

JetBrains, the company behind the excellent Resharper has this build/integration server called TeamCity. I thought that you had to pay to use TeamCity, but the professional version is actually free!

I recently hit a problem with CruiseControl.NET and its limited security so I decided to try TeamCity. The installation was smooth and setting up a project and getting it to build a project (via NAnt) was easy. The problem is however that TeamCity only supports NUnit and since I use xUnit I did not get any test results presented in the TeamCity web interface.

In order to solve this I began writing a custom NAnt task. There is no NAnt xUnit task in the xUnit release or in the codeplex source repository but there is a task for MSBuild and it was pretty easy to port this to an NAnt task. When I had the NAnt task working I added some special log messages. The way you integrate with TeamCity is through specifically formatted messages, for example:

##teamcity[testStarted name='HomeContollerTester ']

##teamcity[testFailed name='testname' message='failure message' details='stack trace']

TeamCity expects live reporting, test by test, as it uses the started/finished messages to time each test and to provide more dynamic reporting while the tests are running. This doesn't play well with the xUnit test runner as there is no callback before each test is executed only after. The TeamCity test report will list all tests as if they executed in less than 1ms:

image

To solve this problem I added the ability to export the test results to a html file (this feature was already present in the MSBuild task). You can publish this html report as an artifact in TeamCity.

Example:
<xunit assembly="XUnitTeamCityTest.dll"        
       html="${results.dir}\test_report.html"      
       workingDir="${out.dir}" />
      
<echo message="##teamcity[publishArtifacts '${results.dir}\test_report.html']" />

The NAnt echo task will just output the message to the build log which TeamCity will parse. The full test report with accurate timing information will then be available in the TeamCity web interface. Like this:

image

I really like how easy it is to integrate artifacts from the build script to the build server and make those publicly available. I will try to contact the xUnit team and see if I can contribute this. TeamCity support is the highest voted feature request for xUnit on codeplex :)

But until then here is the source: XUnit.NAntTasks.zip

I submitted a patch to the MvcContrib project last week containing my fluent interface for route definitions (the one I blogged about last week). It was applied yesterday (revision 541). When I prepared the patch I did some minor changes, for example renamed the route from SagaRoute to MvcRoute (Saga is related to the name of the app I am building).

Some examples:

MvcRoute
  .MappUrl("{controller}/{action}/{id}")
  .ToDefaultAction<HomeController>(x => x.Index(), new {id="0"})
  .AddWithName("Default", routes);

MvcRoute
  .MappUrl("questions/tagged/{tagName}")
  .ToDefaultAction<QuestionsController>(x => x.ViewByTag(""))
  .AddWithName("QuestionsByTag", routes);
  
MvcRoute
  .MappUrl("questions/{id}/{urlName}")
  .WithConstraints(new { id="^[0-9]+$" })
  .ToDefaultAction<QuestionsController>(x => x.ViewQuestion(0))
  .AddWithName("QuestionsById", routes);
  
MvcRoute
  .MappUrl("user/{userName}")  
  .ToDefaultAction<UserController>(x => x.ViewUser(""))
  .AddWithName("UserByName", routes);
    

I added a WithConstraints method. If you do not like the lambda approach but still like the fluent API you can use the WithDefaults method that takes in an anonymous type (like the default MapRoute method do).

imageLast night during a company meeting it was announced that TFS had been chosen as the recommended issue tracking tool. I asked what other tools where  looked at and reviewed and for what particular reasons TFS was chosen over others. Apparently no other issue tracking system was every looked at, TFS fulfilled the requirements and was therefore "good enough".

This is not about Microsoft vs open source, or TFS vs Jira for that matter. TFS is a flexible and competent issue tracking tool, sure I think it has issues compared to other cheaper alternatives but that is beside the point :) I was just saddened by the fact that no alternatives was ever reviewed. When I questioned this fact, I got two comments.

well it is from Microsoft and integrates with visual studio

and

well you can always find something better, this met our needs so why look for something else?

The second comment is one of the worst I have ever heard, of course you cannot look at EVERY other tool. What you can do is a quick Google search to find which are the most popular and have a look at 2-3 of those, or just send out an email to everyone in the company and ask what issue tracking tool they have used and what they think is best and why.

Why be satisfied with "good enough"? How are you going to be constantly improving with that motto?

I know I am overreacting, this was just a recommendation of an issue tracking tool, but it enforces my distrust that some Microsoft development departments choose Microsoft solutions without ever looking at alternatives. Like any company Microsoft do some really great and amazing stuff and some that are not so good.

This reminds me of an interesting discussion on the ALT.NET mailing list: Where did the non alt .net come from anyway? 

Microsoft is trying to be the sole supplier for every possible framework and development tool for the .NET platform. I can understand why they are doing this, but I think there is a negative side to it, I think it limits diversity and innovation. One of the great things about ALT.NET is the embrace of diversity and trying to get rid of the single mindedness that can sometimes characterize .NET development, this is good for everyone as it pushes Microsoft to be better.

In the ASP.NET MVC application I am working on I have a lot of catch-all routes, for example:

routes.MapRoute("History", "history/{*path}",
                new {controller = "History", action = "ViewHistory", path = ""});

The asterisk in the path url segment is a catch-all parameter, which means that everything in the url after "history/" will be captured in the path parameter (not including the querystring). In my scenario I want the same url path mapped to different controller actions depending on querystring parameters . This scenario might not be common for most mvc apps but it led me to write some interesting routing extensions.

This is the sort of route handling I needed:

  • /history/some/path/                         => mapped to action ViewHistory
  • /history/some/path?cs=123               => mapped to action ViewChangeset
  • /history/some/path?r1=123&r2=124   => mapped to action ViewDiff
I think this could be done by using regular expression constraints for the route parameters, but I wanted routes to be defined in a way that was easier and more maintainable. First I tried to extend the MvcRouteHandler and in the GetHttpHandler method check for different querystring parameters and change the "action" route value accordingly. This worked but felt like the wrong way.

What I ended up doing was subclassing the Route class and creating a sort of fluent interface for defining routes. The end result looked like this:

 SagaRoute
    .MappUrl("history/{*urlPath}")
    .IfQueryStringExists("cs")
    .ToAction<HistoryController>(x => x.ViewChangeset("", null))
    .AddWithName("ChangesetDetail", routes);

SagaRoute
   .MappUrl("history/{*urlPath}")
   .IfQueryStringExists("r1", "r2")
   .ToAction<DiffController>(x => x.ViewDiff("", null, null))
   .AddWithName("Diff", routes);

SagaRoute
    .MappUrl("history/{*urlPath}")
    .ToAction<HistoryController>(x => x.ViewHistory("", null, null))
    .AddWithName("History", routes);

SagaRoute is a class that inherits from the Route class defined in System.Web.Routing. The really interesting function here is ToAction which takes a lambda from which it will extract the default controller name, action name and parameter values. Here is the full source code for the SagaRoute class:

public class SagaRoute : Route
{
  public SagaRoute(string url) : base(url, new MvcRouteHandler()) { }

  public static SagaRoute MappUrl(string url)
  {
      return new SagaRoute(url);
  }

  public SagaRoute ToAction<T>(Expression<Func<T, ActionResult>> action) where T : IController
  {
      var body = action.Body as MethodCallExpression;
      Check.Require(body != null, "Expression must be a method call");
      Check.Require(body.Object == action.Parameters[0], "Method call must target lambda argument");

      string methodName = body.Method.Name;
      string controllerName = typeof(T).Name;

      if (controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
      {
          controllerName = controllerName.Remove(controllerName.Length - 10, 10);
      }

      Defaults = LinkBuilder.BuildParameterValuesFromExpression(body) ?? new RouteValueDictionary();
      foreach (var pair in Defaults.Where(x => x.Value == null).ToList())
          Defaults.Remove(pair.Key);

      Defaults.Add("controller", controllerName);
      Defaults.Add("action", methodName);

      return this;
  }

  public SagaRoute AddWithName(string routeName, RouteCollection routes)
  {
      routes.Add(routeName, this);
      return this;
  }

  public SagaRoute IfQueryStringExists(params string[] names)
  {
      if (Constraints == null)
      {
          Constraints = new RouteValueDictionary();
      }

      Constraints.Add("dummy", new QueryStringExists(names));
      return this;
  }
}

This is not a fully featured fluent interface for defining routes, I just did the bare minimum for handling the kind of routes that I needed. Another interesting function is the IfQueryStringExists function which adds a QueryStringExists constraints to the Constraints dictionary. This dictionary can either contain a parameter key and a regular expression string or a parameter key and an object that implements IRouteConstraint.

The QueryStringExists is a very simple class that implements IRouteConstraint. The constraint model is designed to only work with one parameter at a time which is probably ok for most scenarios. What I wanted was a constraint like "if ANY of these parameters exists" which is why when I add the constraint to the dictionary I named the key "dummy". Here is the code for the QueryStringExists constraint:

public class QueryStringExists : IRouteConstraint
{
    public string[] names;

    public QueryStringExists(params string[] names)
    {
        this.names = names;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.UrlGeneration)
            return true;

        var queryString = httpContext.Request.QueryString;

        return names.Where(name => queryString[name] != null).Any();
    }
}

I guess most of this is very specific to my scenario but I think the API for adding routes that I ended up with is a small improvement to the standard way of doing it and could be used in other scenarios. For example the standard route can be rewritten like this:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = "" } // Parameter defaults
    );

SagaRoute
  .MappUrl("{controller}/{action}/{id}")
  .ToDefaultAction<HomeController>(x => x.Index(), new {id=""})
  .AddWithName("Default", routes);

To support this more common scenario I added a ToDefaultAction method, which does the same as ToAction, but in this method you can also pass in defaults for parameters that aren't included in the arguments to the default action.

This will be another post about the MVC view engine spark, by the title of this post and my last post you can safely assume that I really like this view engine.

Since my last post about spark there has been some big updates to the view engine and a bunch of new features.

Conditional attribute

<input type="checkbox" name="chkhello" checked="?{isHelloChecked}"></input>
The conditional ?{boolean} syntax if used as the only thing in an attribute will remove the attribute from the rendering (if the boolean expression is false). If there is text in front of the question mark then only that text will be excluded, for example:
<ul>
  <li each="var product in Products" class="first?{productIsFirst} last?{productIsLast}">
    ${H(product.Name)}
  </li>
</ul>

The above will output:

<ul>
  <li class="first">Alpha</li>
  <li>Beta</li>
  <li>Gamma</li>
  <li class=" last">Delta</li>
</ul>

More loop autovariables

In loops the view engine will automatically provide some loop variables, the name is always the loop variable name plus the suffix: "Index", "IsFirst", "IsLast", "Count". It will only generate loop variables that you use so there is no performance hit if you don't use any of them. IsLast and Count could potentially have a small affect on performance (for example for IEnumerable LINQ lists).

Macros

This is a great little feature to reduce duplication in your views:
<macro name="PrevNextLink" cs="Changeset" className="string">
    <if condition="cs != null">    
        <a href="${Url.RouteUrl('ChangesetDetail', new {cs=cs.Revision})}" class="${className}" >
            ${cs.Message.TrimWithElipsis(50)}
        </a>        
    </if>    
</macro>    

<div class="changeset-nav-links">
    ${PrevNextLink(ViewData.Model.Previous, "prev")}
    ${PrevNextLink(ViewData.Model.Next, "next")}    
</div>

A macro translates to a function that returns a string. This function can then be used anywhere in your view. Great for reusing some small part of a view that you do not feel needs to be a separate view file (partial).

Partial views

Spark has great support for partial view files. You can render content from a partial by using implicit or explicit syntax.

Explicit:
<use file="mypartial" caption="product.Name"/>

This will look for a view file named mypartial.spark

Implicit:
<menuTabs tabs="ViewData.Model.Tabs" />

This will look for a partial file named _menuTabs.spark, first in the current view folder, then in the shared view folder. Partials can access all scoped variables from where it is used, optionally you can set locally scoped variables for the partial by setting attributes (for example the tabs attribute in the above example).

Partial views and inner content

There is a new feature that allows you to send the inner content to a partial view.

Example partial file _boxit.spark:

<div class="boxit">
  <div class="boxit-header">
    ${header}
  </div>
  <div class="boxit-content">                        
    <render/>
  </div>
</div>

This can than be used like this:

<p>
  Something.. 
</p>

<boxit header="Cool box">
  <p>
    Some inner content for the box, can be anything, 
    you can use a another partial in here for example.
  </p>
</boxit>

<p>
  More something.. 
</p>

The idea for this actually came from a college of mine, I thought it was good idea so I submitted it to the spark mailing list and Louis DeJardin did a great job implementing it. He is even working on expanding this to add support for named sections within partials, similar to what MonoRail view components has.

Precompiling

You can now precompile your views, for example you can create a unit test that validates that your views compile successfully:

[Fact]
public void Can_Compile_HistoryViews()
{
    var batch = new SparkBatchDescriptor();

    batch.For<HistoryController>()
        .Layout("application")
        .Include("History")
        .Include("Browse")
        .Include("Changeset");
    
    var assembly = factory.Precompile(batch);

    Assert.NotNull(assembly);
    Assert.Equal(3, assembly.GetTypes().Length);
}

Configuration settings

You can now specify referenced assemblies and included namespaces for all your views, this can be done from web.config or from code. This is great as your views will normally use the same namespaces, for example a domain model / presentation model namespace and a namespace with helpers. You can also specify a base class for the generated view class.

Alternative syntax for named elements

Many features in spark use a name attribute on elements. There is now an alternative syntax, instead of <foo name="bar">  you can write <foo:bar>.

<content name="sidebar">
  xxx
</content>

<use content="sidebar"/>

Alternative:

<content:sidebar>
  xxx
</content:sidebar>

<use:sidebar/>

Summary

There are other new stuff, for example you can instantiate your generated view classes using an IoC container. The trunk version of Spark is already updated to use the recently released MVC Preview 5. For more info checkout the official site dev.dejardin.org, it contains documentation (most of the new stuff seems to be included in the docs), as well as a recent build of the trunk.

On September the 13th there will be an open space ALT.NET "unconference". This conference is organised by the ALT.NET group in Stockholm, big thanks to Joakim Sundén for starting this group and getting this conference together.

The ALT.NET Stockholm group have already had a couple of coding dojos, which resulted interesting discussions especially around TDD.

If you live in or near Stockholm and want to discuss development methodologies or tools or just meet and talk to other developers then sign up now.