NancyFx & Castle Windsor

I’ve just managed to fix a very odd problem with Castle Windsor and NancyFx. The error I was getting wasn’t much help at all really!

Can’t create component ‘Nancy.Routing.DefaultRouteCacheProvider’ as it has dependencies to be satisfied.
‘Nancy.Routing.DefaultRouteCacheProvider’ is waiting for the following dependencies:
– Service ‘System.Func`1[[Nancy.Routing.IRouteCache, Nancy, Version=0.22.2.0, Culture=neutral, PublicKeyToken=null]]’ which was not registered.

I’ve created a bootstrapper which among other this allows me to use a pre-existing container.

    public class NancyBootstrapper : WindsorNancyBootstrapper
    {
        private readonly IWindsorContainer _container;

        public NancyBootstrapper(IWindsorContainer container)
        {
            _container = container;
        }

        protected override IWindsorContainer GetApplicationContainer()
        {
            if (ApplicationContainer != null)
            {
                return ApplicationContainer;
            }

            _container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));
            _container.Register(Component.For<NancyRequestScopeInterceptor>());
            _container.Kernel.ProxyFactory.AddInterceptorSelector(new NancyRequestScopeInterceptorSelector());
            return _container;
        }

        protected override void RegisterBootstrapperTypes(IWindsorContainer applicationContainer)
        {
            // Note: Do NOT do the line below, this will cause the container to be registered twice and Windsor will throw an exception
            // applicationContainer.Register(Component.For<INancyModuleCatalog>().Instance(this));
        }
    }

Thanks to Ricardo Campos for getting me started! But whenever I tried starting nancy in self-host mode I immediately got the “missing IRouteCache” problem.

            var bootstrapper = _container.Resolve<INancyBootstrapper>();

            var uri = WebServerUri;
            _nancyHost = new NancyHost(uri, bootstrapper);

After much googling, head scratching, silent cursing and putting the world to rights a few times, I stumbled across a Stack Overflow answer. After reading through the link provided in the answer (https://github.com/NancyFx/Nancy.Bootstrappers.Windsor/pull/8). I tried adding the suggested fix.

        protected override void ConfigureApplicationContainer(IWindsorContainer existingContainer)
        {
            existingContainer.AddFacility<TypedFactoryFacility>();

            // some other cool stuff!
        }

Hey presto, it was all working and all is well with the world once more, until I hit the next bug that defies logic!

Advertisements

I’m all Moq’d out!

I’m currently working on creating a Hypermedia API, or at least getting as close as I can to one!

In order to avoid the client hitting a dead end when an error occurs, either internally within my code or as a result of a bad request from the client, I wanted to provide links that the client can follow. So, I created an ApiError model class to send in my response in such a case.

    [Hypermedia]
    public class ApiError : Resource
    {
        public string ParentId { get; set; }
        public string ErrorMessage { get; set; }
    }

The [Hypermedia] attribute is just a place holder I use within my Delegating Handler which “enriches” the resources with links. The ParentId is the id used in order to construct links to the home resource and it’s also used for constructing self links and so on.

The links are generated by way of Mark Seamann’s excellent HyprLinkr library, available via Nuget (http://nuget.org/packages/Hyprlinkr/).

My first attempt was to create an extension method to create the response, much like the built in HttpRequestMessage.CreateErrorResponse extension method. This worked great when I tested it using my current favourite chrome extension, POSTman. It returned the error, along with a “back” and “home” link so the client didn’t just hit a dead-end.

For example …

  "errorMessage" : "The was an error, run for the hills!",
  "_links" :
  [
    {
      "rel" : "home",
      "href" : "http://server/api/home/someone@example.com",
      "title" : "home",
      "verb" : "GET"
    }
  ]

So, all is well. I’m a happy bunny….

Until I run my unit tests.

What The Flip?

Why is there red everywhere?!

As it turns out I wrote some legacy (read: un-testable) code. Here’s what I’d come up with …

    public static class HttpRequestMessageExtensions
    {
        public static HttpResponseMessage CreateErrorResponse(
            this HttpRequestMessage request,
            HttpStatusCode statusCode,
            string parentId,
            string errorMessage,
            Action<IResourceLinker, ApiError> addLinks)
        {
            var apiError = new ApiError
            {
                ParentId = parentId,
                ErrorMessage = errorMessage
            };

            if (addLinks != null)
            {
                var routeLinker = _resourceLinkerFactory.GetResourceLinker(request);
                addLinks(routeLinker, apiError);
            }

            return request.CreateResponse(statusCode, apiError);
        }

After spending some time in the debugger trying to figure out why I was getting a null reference exception, I started looking at Mark’s code on github and eventually figured out that the GetRouteData() call was returning null. So, I spent more time trying to figure out a way of getting that to *not* be null. I ended up getting the source code for the aspnetwebstack from codeplex and looking at the code for GetRouteData().

Veering off-topic slightly, I didn’t have git installed on my pc, so I fired up powershell and …

  PS> cinst git

… I used chocolately to install it, restarted powershell and …

  PS> git clone https://git01.codeplex.com/aspnetwebstack

… I was rummaging around the asp.net web stack code 😀

Back on to topic …

After a few failed attempts at getting the null reference to go away it dawned on me that with another layer or two or abstraction I could Moq (on nuget too – https://www.nuget.org/packages/moq) my way out of trouble.

So, thinking about it for a little while I came up with a way of doing all this so I could moq it. Firstly I needed to change CreateApiErrorResponse from an extension method into a “service”, which I could then pass into the relevant controllers. Once I get past the unit test stage I could easily set it up using Castle Windsor. I would also need an IResourceLinker factory.

The Service

    public interface IHttpRequestMessageService
    {
        HttpResponseMessage CreateErrorResponse(
            HttpRequestMessage request,
            HttpStatusCode statusCode,
            string parentId,
            string errorMessage,
            Action<IResourceLinker, ApiError> addLinks);
    }

    public class HttpRequestMessageService : IHttpRequestMessageService
    {
        private readonly IResourceLinkerFactory _resourceLinkerFactory;

        public HttpRequestMessageService(IResourceLinkerFactory resourceLinkerFactory)
        {
            _resourceLinkerFactory = resourceLinkerFactory;
        }

        public HttpResponseMessage CreateErrorResponse(
            HttpRequestMessage request,
            HttpStatusCode statusCode,
            string parentId,
            string errorMessage,
            Action<IResourceLinker, ApiError> addLinks)
        {
            var apiError = new ApiError
            {
                ParentId = parentId,
                ErrorMessage = errorMessage
            };

            if (addLinks != null)
            {
                var routeLinker = _resourceLinkerFactory.GetResourceLinker(request);
                addLinks(routeLinker, apiError);
            }

            return request.CreateResponse(statusCode, apiError);
        }
    }

The Factory

    public interface IResourceLinkerFactory
    {
        IResourceLinker GetResourceLinker(HttpRequestMessage request);
    }

    public class ResourceLinkerFactory : IResourceLinkerFactory
    {
        public IResourceLinker GetResourceLinker(HttpRequestMessage request)
        {
            return new RouteLinker(request, new AttributeBasedRouteDispatcher());
        }
    }

Once I sorted out a few built errors it was time to do some Moqing…

    public class MyControllerTests
    {
        private Mock<IResourceLinkerFactory> _mockResourceLinkerFactory;
        private Mock<IResourceLinker> _mockResourceLinker;
        private IHttpRequestMessageService _httpRequestMessageService;
        private MyController _controller;

        [SetUp]
        public void SetUp()
        {
            const string id = "john.doe@example.com";

            var config = new HttpConfiguration();
            var request = new HttpRequestMessage(HttpMethod.Post, string.Format("http://localhost/api/user/{0}", id));

            _mockResourceLinkerFactory = new Mock<IResourceLinkerFactory>();
            _mockResourceLinker = new Mock<IResourceLinker>();
            _httpRequestMessageService = new HttpRequestMessageService(_mockResourceLinkerFactory.Object);

            _mockResourceLinkerFactory.Setup(x => x.GetResourceLinker(It.IsAny<HttpRequestMessage>()))
                                      .Returns(_mockResourceLinker.Object);

            _mockResourceLinker.Setup(x => x.GetUri(It.IsAny<Expression<Action<MyController>>>()))
                           .Returns(new Uri(string.Format("http://localhost/api/user/{0}", id)));

            _controller = new MyController(_httpRequestMessageService);
        }
    }

Hurrah! It all worked and I could get back to testing what I was actually trying to, which was unrelated to providing links when sending errors to the client. But, I needed this anyway 😀

Since the tests I was working on weren’t testing the presence of the links, I suppose I could have done something like this …

    var _mockHttpRequestMessageService = new Mock<IHttpRequestMessageService>();
    _mockHttpRequestMessageService
        .Setup(x => x.CreateErrorResponse(
            It.IsAny<HttpRequestMessage>(),
            It.IsAny<HttpStatusCode>(),
            It.IsAny<string>(),
            It.IsAny<string>(),
            It.IsAny<Action<IResourceLinker, ApiError>>())
        .Returns(new HttpResponseMessage(...));

Anyway, I hope that helps someone out. It’ll probably be me at some point in the future as my memory is not the best 😉

Displaying embedded web pages in Winforms

I had an application/plugin I wanted to display some license information in and also attribute my use of a public API. So, I figured a nice way to do that would be to drop a web browser control in my winform and then have an embedded resource as the content. So, I created a little webpage and set it’s Build Action to Embedded Resource. A tiny bit of css in the head section and it looked good.

But, I wanted to also display an image in there. I tried a few different ways, but eventually stumbled upon an answer on stackoverflow which suggested encoding the image as a Base64 string. So, I set to work creating a little helper method to load my embedded web page and automatically encode all images on it. I decided to go with using a placeholder to the image, like so …

%IMG("MyProgram.Images.logo.png")%

In order to find out the name of the resource, you may find running this little piece of code helpful …

var names = Assembly.GetExecutingAssembly().GetManifestResourceNames();

So, I used a little regex magic (courtesey of regexhero.net) to find those placeholders, extract the path and do the encoding for me.

    public static class EmbeddedWebPageLoader
    {
        public static string LoadWebPage(string name)
        {
            const string regexPattern = @"%IMG\(\""(?<ImagePath>[^\""]*)\""\)%";
            var assembly = Assembly.GetExecutingAssembly();
            var pageStream = assembly.GetManifestResourceStream(name);
            if (pageStream != null)
            {
                using (var webPageStreamReader = new StreamReader(pageStream))
                {
                    var pageContent = webPageStreamReader.ReadToEnd();
                    var matches = Regex.Matches(pageContent, regexPattern);
                    foreach (Match match in matches)
                    {
                        var imagePath = match.Groups["ImagePath"];
                        var extension = Path.GetExtension(imagePath.Value).Trim(".".ToCharArray());
                        var imageStream = assembly.GetManifestResourceStream(imagePath.Value);
                        if (imageStream != null)
                        {
                            var buffer = new byte[imageStream.Length];
                            imageStream.Read(buffer, 0, (int) imageStream.Length);
                            var imageBase64String = Convert.ToBase64String(buffer);
                            var imgTag = string.Format("<img src='data:image/{0};base64,{1}'/>", extension, imageBase64String);

                            pageContent = Regex.Replace(pageContent, regexPattern, imgTag);
                        }
                    }
                    return pageContent;
                }
            }
            return null;
        }
    }

It works like a dream, I can now use images inside my about box, like so …

webBrowser.DocumentText = EmbeddedWebPageLoader.LoadWebPage("MyProgram.About.html");

Battle with Vista

I used to do all my software development (amongst other things) on my trusty HP laptop. It wasn’t what you’d call a normal laptop. It had 2 gigabytes of RAM and a fast dual core Intel processor. I also had a docking station for it so I could use my lovely Hyundia W240D LCD display and my normal desktop keyboard and mouse. So for all intents and purposes it was a desktop replacement. That is, apart from the speed of the thing, especially when it came to the day-to-day use I put it to as a development machine for working on a large ASP.NET and ASP website project. It seemed to me as a long time builder of my own PCs that the bottleneck was the disk subsystem. For all the right reasons, well one, my laptop was specified with 5400 rpm hard drives. In a laptop that’s a good choice as 7200 rpm hard drives are typically much noisier.

So, I made the decision to build myself a new uber-computer. But me being me, I took it a step further. So, here I am writing this on a completely silent PC. I say silent, but in actual fact it’s not silent, I just can’t hear it. Since I already had a number of devices mounted in a home-built rack, I decided to put my new machine in there and run cabling to my office. All I needed was a DVI lead, USB and an audio extension lead. Anyway, I’ve already detailed the actual build in another web page. This post is about my epic struggle to get vista to a point where I could use it to develop software.

I have decided to gather all my solutions to various problems that stood in my way, both as a future reference and in the hope that it my spare some poor soul from the same stress that I had to go through!

Website Projects/Solutions under Visual Studio 2008

When working with a website in Visual Studio 2008, it needs to be run with elevated privileges. This can be done in a number of different ways, first a temporary solution …..

  • Right-click the shortcut in the Start Menu
  • Select “Run as Administrator”

A permanent solution …

  • Right-click the shortcut
  • Select “Properties”
  • Select the “Shortcut” tab
  • Click the “Advanced” button
  • Tick the “Run as administrator” box
  • Click the “OK” button on both dialogs

There are other ways, such as enabling the administrator account and using that. But the two above ways keep the UAC intact.

Event Logs

Vista is locked down in terms of Event Logs, but there is only a problem when trying to create a new Event Log Source. This is easily solved by manually creating the required Source(s). This is achieved by a little regedit use.

Within the HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventLog key there should be a key for each log.

To create the log …

  • Right-click the EventLog key
  • Select “New” – “Key”
  • Enter the name of your log
  • Press <Enter>

To create the sources …

  • Right-click the HKLMSYSTEMCurrentControlSetServicesEventLog<log name> key
  • Select “New” – “Key”
  • Enter the name of the Source
  • Press <Enter>

Enable ASP Error Messages

By default IIS7 doesn’t send ASP error messages to the browser. Obviously, for development purposes, these are very useful. So, to enable them …

  • Load the IIS Manager
  • Navigate to your website
  • In the “Features View”, double-click the “ASP” icon within the “IIS” section.
  • Open up the “Compilation” section
  • Open up the “Debugging Properties” section
  • Set the “Send Errors To Browser” property to “True”

Enable ASP Parent Path References

In order for ASP to refer to parent folders …

  • Load the IIS Manager
  • Navigate to your website
  • In the “Features View”, double-click the “ASP” icon within the “IIS” section.
  • Open up the “Behavior” section
  • Set the “Enable Parent Paths” property to “True”

Enable ActiveX Controls

ActiveX controls can only be used in 32-bit mode. So, if your website makes use of them you will need to change your website to run as a 32-bit application. To do this …

  • Load the IIS Manager
  • Navigate to the “Application Pools” section
  • Right-click your website’s application pool
  • Select “Advanced Settings…”
  • Open up the “General” section
  • Set the “Enable 32-Bit Applications” property to “True”

Javascript error – ‘Telerik’ is undefined

This one is specific to using Telerik controls. Add the following to the web.config file in the <system.webserver> <handlers> section

<add name="Telerik.Web.UI.WebResource"  path="Telerik.Web.UI.WebResource.axd" verb="*" type="Telerik.Web.UI.WebResource, Telerik.Web.UI" />

This is by now means an exhaustive list, it’s just a small collection of the things I needed to fight my way through before I could use my machine in anger as a development workstation.

Javascript error when using Microsoft ReportViewer control

This is similar to the above in that it needed the following adding to the web.config file in the <system.webserver> <handlers> section

<add name="Reserved-ReportViewerWebControl-axd" path="Reserved.ReportViewerWebControl.axd" verb="*" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/></pre>

The solution was found here

Visual Studio 2008 + Resharper = Immediate exit!

So, I started work today ready to try and fix yesterdays lingering problems. I load up Visual Studio 2008, click on my website link in the start window, it starts to load getting as far as telling me I have 11 projects in my solution, then it exits. What ??!?!?!?

No error message, no visible crash of any kind, not even a BSOD (Blue Screen of Death). So after 5 minutes of cursing and chuntering at the sheer stupidity of what just happened, I started looking for a solution. My first port of call was the Event Viewer, I found this error:-

.NET Runtime version 2.0.50727.1434 – Fatal Execution Engine Error (79FEC5F0) (80131506)

On googling it I find that many other people are having the exact same issue. What’s more there didn’t seem to be a common solution that fixed the problem for all. The first thing I checked was for the existence of any Manifest tags in any of my included csproj files, as that was suggested as a possible cause. No joy there. Next stop was Add-Ins, specifically Resharper as I’d seen that mentioned a few times in my google search results. I disabled the three add-ins I have installed and tried reloading the website solution. Eureka!! it loaded.

So, it was one of my add-ins. I re-enabled them one at a time, re-loading the website solution each time. Well, it turned out to be Resharper causing the problem after all. So, it’s now disabled. I’m very frustrated by this, as I built a new development PC with enough raw grunt to be able to run things like that. My development laptop just grinded to a halt with Resharper installed. So, I’m basically back to square one.

Anyway, I hope this helps someone out there get past a very annoying and frustrating problem. I still cannot believe the stupidity of just having a program, whether it’s visual studio or even something as simple as notepad, just silently close itself down with no indication of what went wrong. Having to look in the Event Viewer to find the solution is next to useless. I’d have though a piece of software such as Visual Studio would be more likely to throw up an error, as the people using it are by definition more technically minded.

Rant over, and back to work.

Tooltips on disabled buttons

After searching the web quite extensively looking for a solution to this problem, i found many other people were having the same problem. But none had an answer, so after a few hours of hacking around i have managed to come up with a solution. It’s not pretty (it uses win32 api calls), but it does the job.
 int WM_MOUSEMOVE = 0x0200;

[StructLayout(LayoutKind.Sequential)]
 public class POINT
 {
public long x;
public long y;
 }

[DllImport("user32", CharSet=CharSet.Auto)]
 public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, POINT lParam);
 
When a button is disabled it does not receive any mouse related messages. The parent of the button does receive them. So i put a MouseMove event handler in place for my form. I still use the standard Winforms tooltip control to hold the tooltip text for the button.
 private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
 {
Point pt = PointToClient(Cursor.Position);
Control control = GetChildAtPoint(pt);
if (control != null)
{
if (control is Button &amp;&amp; !control.Enabled)
{
string tip = toolTip1.GetToolTip(control);
if (tip.Length &gt; 0)
{
POINT point = new POINT();
                  point.x = Cursor.Position.X;
                  point.y = Cursor.Position.Y;
                  SendMessage(control.Handle, (int) WindowsMessages.WM_MOUSEMOVE, 0, point);
              }
          }
}
 }
 
This seems to work perfectly. Hope it helps someone else out