Error: Failed to compile both on .NET 4.5 and on .NET 4.0. 4.5 Exception: System.IO.IOException: The file exists.

Today I had a weird issue with a Microsoft IIS web-server. The latest .NET Framework was correctly installed and registered on the server, but when I put my .NET code in the web directory and browsed to it from a remote browser I got the standard .NET error page. I would get the error regardless of whether I was trying to access a page served by .NET or a basic HTML page hosted on the server. I confirmed that IIS was working correctly by removing all files (including the web.config file) from the web-directory and putting in a basic test HTML page on its own. The test page rendered correctly from a remote browser.

Having put the .NET code back in, I browsed to a .NET URL locally on the web-server in order to get a full view of the error message. The rather strange error was as follows:

File Exists Error

In order to help people find this page in search engines, the full text was as follows:

Server Error in '/' Application.

Failed to compile both on .NET 4.5 and on .NET 4.0. 4.5 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder). 4.0 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder) 
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

 Exception Details: System.InvalidOperationException: Failed to compile both on .NET 4.5 and on .NET 4.0. 4.5 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder). 4.0 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder)

Source Error: 


 An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.  

Stack Trace: 



[InvalidOperationException: Failed to compile both on .NET 4.5 and on .NET 4.0. 4.5 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder). 4.0 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder)]
   HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder) +712

[InvalidOperationException: System.InvalidOperationException: Failed to compile both on .NET 4.5 and on .NET 4.0. 4.5 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder). 4.0 Exception: System.IO.IOException: The file exists.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Path.InternalGetTempFileName(Boolean checkHost)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileInternally(String fileName, List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String outputFolder, String compilerVersion, Int32 tryCount)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder)
   at HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder)
ImageRuntimeVersion: v4.0.30319]
   HibernatingRhinos.Profiler.Appender.Util.GenerateAssembly.CompileAssembly(List`1 sources, HashSet`1 assemblies, HashSet`1 defineSymbols, String assemblyFileName, String outputFolder) +1042
   HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.RegisterAppenderUsingNHibernateLogger() +314
   HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(NHibernateAppenderConfiguration configuration) +53
   XXXXX.App_Start.NHibernateProfilerBootstrapper.PreStart() in c:\TeamCity\buildAgent\work\XXXXX\App_Start\NHibernateProfilerBootstrapper.cs:18

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +260
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +146
   System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +34
   WebActivator.BaseActivationMethodAttribute.InvokeMethod() +288
   WebActivator.ActivationManager.RunActivationMethods() +698
   WebActivator.ActivationManager.RunPreStartMethods() +46
   WebActivator.ActivationManager.Run() +68

[InvalidOperationException: The pre-application start initialization method Run on type WebActivator.ActivationManager threw an exception with the following error message: Exception has been thrown by the target of an invocation..]
   System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection`1 methods, Func`1 setHostingEnvironmentCultures) +874
   System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods) +169
   System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath, Boolean& isRefAssemblyLoaded) +166
   System.Web.Compilation.BuildManager.ExecutePreAppStart() +176
   System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +882

[HttpException (0x80004005): The pre-application start initialization method Run on type WebActivator.ActivationManager threw an exception with the following error message: Exception has been thrown by the target of an invocation..]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +579
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +112
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +716

  


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1055.0  

I found this article on stack overflow which helped me to solve the problem. The answer was simply to clear down the %TEMP% folder, which for me was C:\windows\temp. Apparently, if there are more than 65,535 files in there .NET is not able to serve web-pages through IIS. There were hundreds of thousands of files in the folder so I couldn’t even browse to it using Windows Explorer. It ended up being a command prompt job:

File Exists Error Command

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>cd c:\Windows\Temp

c:\Windows\Temp>del c:\Windows\Temp\*.*
c:\Windows\Temp\*.*, Are you sure (Y/N)? y

That fixed the problem.

Beware! ASP.NET MVC ActionFilterAttributes are cached between requests!

My colleagues and I recently encountered a very strange bug in an ASP.NET MVC web-site which seemed to be to do with NHibernate. The error suggested that we were trying to use a session that had already been closed. We could not find any sign of a closed session anywhere within the controllers in our project. Eventually we pinned the error down to a repository (containing an NHibernate session) referenced in an ActionFilterAttribute. The guy that wrote the code assumed that the repository would be referenced freshly by the attribute each time it was used, but of course it wasn’t; the .NET engine was helpfully caching the attribute between calls so that some users were getting sessions intended for other users.

The moral of the story is to make sure your ActionFilterAttributes are always stateless.

The following simple demonstration highlights this. Here is an ActionFilterAttribute which stores the date and time in a field on construction:

using System;
using System.Web.Mvc;

namespace WebTest.Attributes
{
    public class TestActionFilterAttribute : ActionFilterAttribute
    {
        private readonly DateTime _now;

        public TestActionFilterAttribute()
        {
            _now = DateTime.Now;
        }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Put the date into a ViewBag property:
            filterContext.Controller.ViewBag.DateTime = _now;
        }
    }
}

This is then used in a controller as follows:

using System;
using System.Text;
using System.Web.Mvc;
using WebTest.Attributes;

namespace WebTest.Controllers
{
    public class HomeController : Controller
    {
        [TestActionFilter]
        public ActionResult Index()
        {
            const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss.fffffff";

            var text = new StringBuilder();

            text.AppendFormat("DateTime called directly: {0}<br/>", DateTime.Now.ToString(dateTimeFormat));
            text.AppendFormat("DateTime taken from ActionFilterAttribute: {0}<br/>", ViewBag.DateTime.ToString(dateTimeFormat));

            return Content(text.ToString());
        }
    }
}

If you refresh the page a few times you’ll notice that the time coming from the ViewBag (which originates from the attribute) remains the same while the current time continues to increase, proving that the attribute isn’t being instantiated for each web call. You have been warned!

Using Visual Studio to run web-sites locally using real domains

Visual Studio is great for developing and testing web-sites, but by default it runs them under a localhost address using a randomly generated port number, as given in the property page for the web-site:

Visual Studio Real Domains 01

This is fine, but sometimes it’s useful to have sites run at a location that looks more like a real internet URL, especially if you plan on including functionality that manipulates the URL for redirects etc… I’ve also encountered issues creating cookies using the default http://localhost:xxxx address.

Fortunately, there’s a hosts file trick you can use to make Visual Studio run sites under more realistic URLs. First point 127.0.0.1 at the URL you want to use in your hosts file, for example:

127.0.0.1 www.testing.com

Note though that if the URL you are using points to a real web-site on the internet, you won’t be able to access that site again until you remove the entry from your host file.

Then edit the property pages so that you’re using the Visual Studio Development Server, a specific port (rather than an auto-assigned port) and a custom start URL containing your chosen port number and test URL, for example:

http://www.testing.com:1455

Your property pages should look like this:

Visual Studio Real Domains 02

Then, when you run your web-site using Visual Studio, it will use http://www.testing.com:1455 as the base URL. All paths relative to that should work as expected:

Visual Studio Real Domains 03

Exotic .NET XML configuration file sections

The .NET framework makes application configuration really simple by supplying an out-of-the-box XML configuration file structure and associated classes to access the information contained within it.

By default, it allows configuration key-value pairs to be set and retrieved easily at run time. For example, the following configuration settings:

  <appSettings>
    <add key="ServerName" value="WinDB1"/>
    <add key="DatabaseName" value="MyData"/>
    <add key="EnableFeature" value="true"/>
  </appSettings>

…can be retrieved using:

var appSettingsReader = new AppSettingsReader();

var serverName = (string)appSettingsReader.GetValue("ServerName", typeof(string));
var databaseName = (string)appSettingsReader.GetValue("DatabaseName", typeof(string));
var enableFeature = (bool)appSettingsReader.GetValue("EnableFeature", typeof(bool));

…or (if you add a reference to System.Configuration):

var serverName = ConfigurationManager.AppSettings["ServerName"];
var databaseName = ConfigurationManager.AppSettings["DatabaseName"];
var enableFeature = bool.Parse(ConfigurationManager.AppSettings["EnableFeature"]);

…although as per a past post of mine, Encapsulated and strongly-typed access to .NET configuration files I don’t recommend that you litter your code with references to AppSettingsReader (or ConfigurationManager), but instead that you wrap all configuration up in a class so that settings are encapsulated away.

It is often necessary to hold more complex configurations though. Many developers I’ve worked with have tried to use the key-value model to store such settings, using a single string with various delimiters to hold separate different values. For instance, given a person construct with an ID, title, first name, last name and birth date attributes, some developers would be tempted to do something like this:

  <appSettings>
    <add key="Person1" value="I:1|T:Mr|F:Joe|L:Bloggs|D:1980-01-01"/>
  </appSettings>

…and then use string split functions to populate a Person class when reading information from the configuration file. While this approach works, it results in brittle, hard to read configuration files and complex string logic to take strings apart.

Instead, it is better to use the exotic configuration capabilities included in the framework. Here is an example demonstrating how you might store configuration information to populate the following Person class:

using System;

namespace ConfigurationExample
{
    public class Person
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
    }
}

The configuration file to store such settings might look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  <configSections>
    <section name="people" type="ConfigurationExample.PeopleConfigurationSectionHandler, ConfigurationExample" />
  </configSections>
  
  <people>
    
    <person id="1">
      <title>Mr</title>
      <firstName>Joe</firstName>
      <lastName>Bloggs</lastName>
      <birthDate>
        <year>1980</year>
        <month>1</month>
        <day>1</day>
      </birthDate>
    </person>

    <person id="2">
      <title>Miss</title>
      <firstName>Jane</firstName>
      <lastName>Black</lastName>
      <birthDate>
        <year>1984</year>
        <month>2</month>
        <day>3</day>
      </birthDate>
    </person>
    
  </people>
  
</configuration>

A class implementing IConfigurationSectionHandler must be written to read this exotic configuration file structure; you will need a reference to System.Configuration in order to use this interface. The location of your class is given in the ‘configSections’ declaration at the top of the file. In this case the framework is being instructed to look for a class with name and namespace ‘ConfigurationExample.PeopleConfigurationSectionHandler’ in the ‘ConfigurationExample’ DLL/project in order to read the configuration section named ‘people’.

That class could look something like this:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Xml;

namespace ConfigurationExample
{
    public class PeopleConfigurationSectionHandler : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, XmlNode section)
        {
            var people = new List<Person>();

            foreach (XmlNode node in section.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Comment)
                {
                    continue;
                }

                var id = GetAttributeInt(node, "id");
                var title = GetChildNodeString(node, "title");
                var firstName = GetChildNodeString(node, "firstName");
                var lastName = GetChildNodeString(node, "lastName");

                var birthDateNode = GetChildNode(node, "birthDate");

                var birthDateYear = GetChildNodeInt(birthDateNode, "year");
                var birthDateMonth = GetChildNodeInt(birthDateNode, "month");
                var birthDateDay = GetChildNodeInt(birthDateNode, "day");

                people.Add(new Person
                {
                    Id = id,
                    Title = title,
                    FirstName = firstName,
                    LastName = lastName,
                    BirthDate = new DateTime(birthDateYear, birthDateMonth, birthDateDay),
                });
            }

            return people;
        }

        private static string GetAttributeString(XmlNode node, string attributeName)
        {
            try
            {
                return node.Attributes[attributeName].Value;
            }
            catch
            {
                var message = string.Format("Could not read attribute named '{0}' in people section of configuration file", attributeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static int GetAttributeInt(XmlNode node, string attributeName)
        {
            try
            {
                var value = GetAttributeString(node, attributeName);
                return int.Parse(value);
            }
            catch
            {
                var message = string.Format("Could not convert value stored in attribute named '{0}' to an integer", attributeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static XmlNode GetChildNode(XmlNode parentNode, string nodeName)
        {
            try
            {
                return parentNode[nodeName];
            }
            catch
            {
                var message = string.Format("Could not find node named '{0}' in people section of configuration file", nodeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static string GetChildNodeString(XmlNode parentNode, string nodeName)
        {
            try
            {
                return parentNode[nodeName].InnerText;
            }
            catch
            {
                var message = string.Format("Could not read node named '{0}' in people section of configuration file", nodeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static int GetChildNodeInt(XmlNode parentNode, string nodeName)
        {
            try
            {
                var value = GetChildNodeString(parentNode, nodeName);
                return int.Parse(value);
            }
            catch
            {
                var message = string.Format("Could not convert value stored in node named '{0}' to an integer", nodeName);
                throw new ConfigurationErrorsException(message);
            }
        }
    }
}

Although there is quite a lot of code there, it’s all pretty simple. More importantly, it’s not too brittle and very simple to extend should you wish to add more attributes to the Person class.

The method required by the IConfigurationSectionHandler interface is Create:

public object Create(object parent, object configContext, XmlNode section)

This is what gets called when the framework asks for the contents of the ‘people’ section. The ‘section’ parameter contains the people node from the XML. In essence, the code creates a list in which Person objects are stored, and loops over the child nodes in order to extract the correct information.

There are two important points to note about the code:

1) The code that detects for the presence of XML comments:

if (node.NodeType == XmlNodeType.Comment)
{
    continue;
}

…ensures that developers don’t break the code by adding comments into the XML.

2) All the helper methods in the class (e.g. GetAttributeString, GetChildNodeString, etc…) must expect there to be issues with the XML and throw meaningful, self-explanatory exceptions when things do go wrong. When there are problems with these types of sections it is not always obvious what the problem is from the default exceptions .NET throws (particularly if you’re using this technique in the start up code of a Windows Service) so you will save yourself a lot of head scratching further down the line by writing good error messages. The chances are that you will have more than one section handler in your project so it’s a good idea to encapsulate such helper methods away in an abstract ConfigurationSectionHandler base class to cut down on duplication and to promote reuse.

Assuming you have registered your section handlers correctly in the ‘configSections’ declaration, you can retrieve the Person objects as follows:

var people = (IList<Person>)ConfigurationManager.GetSection("people");

Since the IConfigurationSectionHandler interface uses the ‘object’ type as its return value you need to cast the result to the correct type. It would have been nice if the interface was made generic, but I guess you can’t have everything!

If you’re following the advice in my previous post on configuration encapsulation, you’ll probably want to wrap this call up in your ConfigurationFile class, as follows:

using System.Collections.Generic;
using System.Configuration;

namespace ConfigurationExample
{
    public class ConfigurationFile
    {
        private readonly IList<Person> people;

        public ConfigurationFile()
        {
            people = (IList<Person>)ConfigurationManager.GetSection("people");
        }

        public IList<Person> People
        {
            get
            {
                return people;
            }
        }
    }
}

Note that a reference to the Person list is stored when the class constructs to save the running the cast each time you want to retrieve the contents of the configuration file section.

In summary, it’s a little more work to write exotic configuration file sections, but the advantages over brittle, difficult to extend key-value implementations is certainly worth the extra effort.

NHibernate and log4net

Here’s a quick trick for people using NHibernate and log4net within their .NET applications. (…and if you’re not using NHibernate or log4net, you should seriously think about it!)

Add the following to your log4net configuration to find out what’s going on inside NHibernate:

  <logger name="NHibernate">
    <level value="DEBUG" />
  </logger>
  <logger name="NHibernate.SQL">
    <level value="DEBUG" />
  </logger>

As those kind folks at NHibernate have already set up the loggers behind the scenes, everything just works. The SQL logger is especially useful as it’ll show you explicitly which SQL statements are being generated by NHibernate. You can adjust the levels of NHibernate logging independently of your normal application logging, which is useful as the NHibernate logs tend to be pretty verbose.

The full configuration will look something like this:

<log4net>
  <appender name="TraceAppender" type="log4net.Appender.TraceAppender" >
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%d %-5p- %m%n" />
    </layout>
  </appender>
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="Application.log"/>
    <appendToFile value="true"/>
    <rollingStyle value="Date"/>
    <datePattern value="yyyy-MM-dd'.log'"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
    </layout>
  </appender>
  <root>
    <level value="DEBUG"/>
    <appender-ref ref="TraceAppender"/>
    <appender-ref ref="RollingFileAppender"/>
  </root>
  <logger name="NHibernate">
    <level value="ERROR" />
  </logger>
  <logger name="NHibernate.SQL">
    <level value="ERROR" />
  </logger>
</log4net>

Using the Return key with Back and Next buttons on web-sites

When it boils down to it, most sites on the web are just gloried data crunchers. Users enter information, which the system churns up and splits out again at some point in the future, potentially to a different user.

If a site requires a lot of information, it is common to see multistage wizards, with each stage asking for a small portion of the information. Each stage usually has a Back button and a Next button. Convention and common sense dictate that the Back button should be on the left, and the Next button on the right as in the following example:

Type something here:
… and here:

NB: The onclick events return false to prevent the page from actually submitting.

This all seems to works fantastically, and even uses tabindex to ensure that the user tabs onto the Next button before the Back button… until someone comes along that prefers to use the Return key to submit the form, instead of using the mouse or tabbing to the Next button. In this case, the Return key will call the first submit button it can find, which in this case is the Back button. This is not the expected behaviour! Put the cursor in one of the input fields and click Return to see this in action.

One solution to correct this would be to use floats and/or JavaScript to try and reverse the order the buttons are displayed in while still having the Next button placed highest in the HTML to ensure that it would respond to the Return key. However, if a user disables CSS and/or JavaScript this solution will fail. A simpler option is to create a hidden submit button as the first element within the form, which performs the desired Return key operation. The order of any other (visible) buttons on the form is then irrelevant.

The following form demonstrates this:

Type something here:
… and here:

Again, put the cursor in one of the input fields and click Return to see this in action. The only downside to this is that the user will see another submit button if they disable CSS, but in most cases I think it is still the best solution.

Simple trick to help prevent click-jacking

Click-jacking is a technique used by hackers to get you to interact with websites without your consent or knowledge. An example would be to get you to click a Like button on a Facebook page without you realising it. The trick with click-jacking is misdirection. One way to achieve this is to show you a friendly looking site, preferably a site which you are already familiar with, but where the buttons perform actions other than those you expect. This can be achieved by hosting the friendly site in an iframe, with fake buttons floated over the top of the real buttons. These fake buttons can then perform unintended actions, such as submitting a Like to Facebook.

You can test whether your website is vulnerable using the following HTML snippet:

<html>
<head>
<title>Clickjack test page</title>
</head>
<body>
<p>Website is vulnerable to clickjacking!</p>
<iframe src="http://www.mywebsite.com" width="1000" height="1000"></iframe>
</body>
</html>

If you can see the text Website is vulnerable to clickjacking! when you look at the code in a browser your site could be used as a target for click-jacking.

A simple way to prevent this kind of attack is to include the following JavaScript at the top of your site:

<script type="text/javascript">
// Prevent the page from being vulnerable to click jacking
if (self == top) {
var theBody = document.getElementsByTagName('body')[0];
theBody.style.display = "block";
} else {
top.location = self.location;
}
</script>

The JavaScript checks to see if the containing page is the top-most entity in the HTML served to the user. If not, then the whole browser is re-directed to the address of the containing page, thus removing the iframe.

Obviously this won’t work if users don’t have JavaScript enabled, but for the sake of a few lines of trivial JavaScript it’s worth adding this to your site.

ASP.NET MVC controller dependency injection using Castle Windsor

In a previous post I looked at basic dependency injection. In this post I demonstrated dependency injection using a simple example in which all functionality in the application was wrapped up in a single class (TimeWriter) with an associated interface (ITimeWriter). The application uses the dependency injection framework to get an instance of this class by its interface. In the process of doing this, all dependencies within the class are also satisfied. The application can then run as normal and write the date and time to the screen.

This approach is fine for console applications as they usually only have one entry point (the Main method) and from there we have complete control over the all code that runs once the application has started. Including dependency injection in ASP.NET MVC web-applications isn’t so straightforward as by default we don’t have control over how code runs right from the start of a user request. The MVC routing engine interprets the request, maps this to a controller, instantiates the controller (using the default controller factory) and calls the correct method on the controller instance. We then get to steer the code execution within the controller method. From a programming perspective, MVC development is like writting an application with multiple entry points contained in multiple controllers.

As we don’t get to instantiate the controller for ourselves there is no obvious way to include dependency injection, unless we write a class and interface for every controller operation and register them with the dependency injection engine in an analogous fashion to the console application example. This would work but it’s clearly not a good idea!

Fortunately ASP.NET MVC allows us to specify custom controller factories, and Castle Windsor includes classes to make it very simple to include dependency injection in this customisation process. Once configured, you can include dependencies as properties in your controllers which, along with the controllers themselves, are resolved by Castle Windsor each time a user request is received.

This time I’m starting with an Empty ASP.NET MVC application using the Razor view engine. The application and the containing solution are called ControllerInjection. Once created, I use NuGet to add a reference to Castle Windsor. My starting point thus looks like this:

Controller Injection 01

As in my basic dependency injection post I’m going to use Watch and IWatch as my example dependencies:

using System;

namespace ControllerInjection
{
    public interface IWatch
    {
        DateTime GetTime();
    }
}
using System;

namespace ControllerInjection
{
    public class Watch : IWatch
    {
        public DateTime GetTime()
        {
            return DateTime.Now;
        }
    }
}

These have been added to the solution as follows:

Controller Injection 02

Now I’m going to include a controller called HomeController:

Controller Injection 03

This contains the following code:

using System.Web.Mvc;

namespace ControllerInjection.Controllers
{
    public class HomeController : Controller
    {
        public IWatch Watch { get; set; }

        public ActionResult Index()
        {
            var text = string.Format("The current time on the server is: {0}", Watch.GetTime());
            return Content(text);
        }
    }
}

The key point here is the property called Watch with type IWatch. This is the dependency which will be injected at runtime. To save having to write a new view the Index method returns raw content.

The next component to implement is our custom controller factory. I’ve included this in a folder called DependencyInjection:

Controller Injection 04

The code inside ControllerFactory is as follows:

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.MicroKernel;

namespace ControllerInjection.DependencyInjection
{
    public class ControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel kernel;

        public ControllerFactory(IKernel kernel)
        {
            this.kernel = kernel;
        }

        public override void ReleaseController(IController controller)
        {
            kernel.ReleaseComponent(controller);
        }

        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
            {
                throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
            }

            return (IController)kernel.Resolve(controllerType);
        }
    }
}

This class extends the DefaultControllerFactory, overriding the methods to get and release controllers. Note that the Castle Windsor kernel is used to resolve each controller by the type of controller required.

The next thing to add is a dependency injector:

Controller Injection 05

using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Castle.Windsor.Installer;

namespace ControllerInjection.DependencyInjection
{
    public static class Injector
    {
        private static readonly object InstanceLock = new object();

        private static IWindsorContainer instance;

        public static IWindsorContainer Instance
        {
            get
            {
                lock (InstanceLock)
                {
                    return instance ?? (instance = GetInjector());
                }
            }
        }

        private static IWindsorContainer GetInjector()
        {
            var container = new WindsorContainer();

            container.Install(FromAssembly.This());

            RegisterInjector(container);
            RegisterControllers(container); 
            RegisterTimeComponents(container);
            
            return container;
        }

        private static void RegisterTimeComponents(WindsorContainer container)
        {
            container.Register(
                Component.For<IWatch>()
                .ImplementedBy(typeof(Watch))
                .LifeStyle.Singleton);
        }
        
        private static void RegisterControllers(WindsorContainer container)
        {
            var controllerFactory = new ControllerFactory(container.Kernel);
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);

            container.Register(
                    Classes.FromThisAssembly()
                    .BasedOn(typeof(IController))
                    .If(t => t.Name.EndsWith("Controller"))
                    .If(t => t.Namespace.StartsWith("ControllerInjection.Controllers"))
                    .Configure(c => c.LifestylePerWebRequest()));
        }

        private static void RegisterInjector(WindsorContainer container)
        {
            container.Register(
                Component.For<IWindsorContainer>()
                .Instance(container));
        }
    }
}

This is very similar to the injector in my basic dependency example, apart from the addition of a method to register controllers. Crucially, this method also registers our customer controller factory. Note that the lifestyle of each controller is set using LifestylePerWebRequest. This ensures that each new request gets its own controller instance.

As the controller factory is only registered once the injector singleton instance has been instantiated, we need to make sure that we initialise the injector when the application starts up. I’ve done this in the Application_Start method of the Global.asax class:

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using ControllerInjection.DependencyInjection;

namespace ControllerInjection
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            // Ensure the dependency injection has been initalised:
            var injector = Injector.Instance;

            /* Normally you would do something with the injector here, like writing an entry to 
             * the log stating that the application had started. */

            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }
}

In practice this doesn’t prove to be a problem as most applications will involve some kind of logging tool (such as Log4Net) which will be obtained from the dependency injection engine. It is usual to log the fact that the application starts, so the injector gets instantiated anyway.

Running the code results in the following string being written to the screen as expected:

The current time on the server is: 11/04/2013 21:59:36

Simple AJAX ASP.NET MVC web-pages that work without JavaScript

AJAX, .NET 4, MVC etc… work together to make web-development very simple, and when Microsoft introduced @Ajax.BeginForm(…) it looked as though life couldn’t get any easier. However, now that jQuery is integrated into Visual Studio as well, I think there are better ways of building AJAX enabled web-pages that using Microsoft’s take on AJAX.

In this post I’ll be building an example solution that is AJAX enabled using jQuery, but works fine if the user has JavaScript switched off. (Although I’m not sure how many people that is this days. In 2010 some say it was around 2% of users but probably less now, although there are still going to be users with a valid reason why they need to keep it disabled.)

So, the final solution is going to look like this:

Simple Ajax 1

I started with an empty MVC 4 project in Visual Studio 2010 and added references to jQuery using the awesome NuGet.

IndexViewModel in the AjaxTest.Models.Home namespace looks like this:

namespace AjaxTest.Models.Home
{
    public class IndexViewModel
    {
        public string Value { get; set; }
    }
}

…it’s just a simple POCO with a single field. The Index.js file in the folder Scripts\Home\Index.js looks like this:

$(function () {
    $('form').submit(function () {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                $('#Target').html(result);
            }
        });
        return false;
    });
});

This looks for a form element and wires up an AJAX call in to the form submit event using jQuery. When the AJAX call completes, any data received is written to a div called Target. If this was anything other than a simple demonstration I would handle errors with a suitable pop-up. The ‘return false;’ statement at the end is really important. This tells JavaScript not to allow the form submit event to bubble up as normal when the code declared here completes.

Next is the Index.cshtml file, which is the display part of the application:

@model AjaxTest.Models.Home.IndexViewModel
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <script language="javascript" type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.9.1.js")"></script>
    <script language="javascript" type="text/javascript" src="@Url.Content("~/Scripts/Home/Index.js")"></script>    
    <title>Index</title>
</head>
<body>
    <div>
        @using (Html.BeginForm("Index", "Home"))
        {
            <div><input type="submit" value="Click to Update" /></div>
            <div id="Target">@Model.Value</div>
        }
    </div>
</body>
</html>

References to both jQuery and my own JavaScript file have been added, along with a model declaration. Inside the body tag is a normal HTML form, a submit button and the div that will be targetted by my AJAX call.

Finally, here is the code for the controller that binds everything together:

using System.Web.Mvc;
using AjaxTest.Models.Home;
using System;

namespace AjaxTest.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var viewModel = new IndexViewModel { Value = "No Value" };
            return View("Index", viewModel);
        }

        [HttpPost]
        public ActionResult Index(object formData)
        {
            var newValue = "Value: " + DateTime.Now;

            // Use an AJAX dialog if possible:
            if (Request.IsAjaxRequest())
            {
                return Content(newValue);
            }

            return View("Index", new IndexViewModel { Value = newValue });
        }
    }
}

The Get method creates a view model for the initial state of the page and renders our index page. The Post method is a little more interesting. This uses the Request.IsAjaxRequest() to determine whether the Post was performed using AJAX or good-old postbacks. If the former is true, some text (containing the time) is returned which our JavaScript function will insert into the div named Target. If not, the entire form is returned, still using the text that would have been passed back had JavaScript been enabled in the client browser.

The end result that the user receives is the same regardless of whether they have JavaScript enabled or not, but in cases where they do, a postback is avoided.

Thank you jQuery!

Linking JavaScript and CSS files

As well as hopefully helping other people out, one objectives of this blog is to act as an aide-memoire as I often find myself looking up the same things on Google over and over again, or thinking “I knew how to do that two months ago”. So, I’ve included a category called “Aides-Memoires” which contains posts only intended to jog my memory so that I don’t have to keep repeating the same Google searches. This post is the first of this type.

Despite being heavily involved in development using web-technologies for over 10 years, one thing I can never seem to remember is how to declare JavaScript and CSS files in the section of my HTML pages. This is extremely basic stuff but I can never remember the syntax! So, here is my aide-memoire:

JavaScript:

<script language="javascript" type="text/javascript" src="scripts/myScripts.js"></script>

CSS:

<link rel="stylesheet" type="text/css" href="styles/myStyles.css" />

Notice that in the above examples the linked JavaScript and CSS files need to be in folders called ‘scripts’ and ‘styles’ respectively in order for the links to work, and that these folders must exist at the same level as the page that is referencing them. If you were to move the referencing page to a sub-folder on the web-server for example, your linked files would no longer be accessible. I would call this a brittle solution.

If you’re lucky enough to be using ASP.NET MVC you also have the option of getting the .NET Framework to work out the relative paths to the files you need to reference. If you’re using the Razor engine, this is coded as follows:

JavaScript:

<script language="javascript" type="text/javascript" src="@Url.Content("~/scripts/myScripts.js")"></script> 

CSS:

<link rel="stylesheet" type="text/css" href="@Url.Content("~/styles/myStyles.css")" />

The tilde (~) simply means “start from the root level of my website”. This is a far less brittle solution.

Update:

I’ve just read that the Razor version 2 engine in ASP.NET MVC 4 is smart enough to not need the @Url.Content() helper. It automatically resolves tildas, so the following will suffice:

<script language="javascript" type="text/javascript" src="~/scripts/myScripts.js" ></script>

CSS:

<link rel="stylesheet" type="text/css" href="~/styles/myStyles.css" />

As well as being robust when files are moved around, an added benefit is that Intellisense still works correctly.