Monday, 16 August 2010

Head of Applications Development

So all has been quiet on the blog front for a few weeks now, but I have a valid reason this time - honest!

I've been busy getting to grips with my new role at Esendex as 'Head of Applications Development'. Neadless to say I'm very busy at the moment with planning, coding (although not as much coding as I'd like) and improving the applications team's agility. At the moment the days are passing me by very quickly!

I've got lots of blog post ideas so as soon as I get round to it they'll be up. Expect more Asp.Net MVC, TDD and hopefully some BDD posts popping up very soon indeed :)

Thursday, 24 June 2010

Multiple types were found that match the controller

I'm starting to make use of the new Areas feature in my MVC 2 applications. I've found it great for separating my applications into distinct sections rather than staring at a massive list of controllers/views all bundled into one folder. I came across an issue when I created a controller with the same name as a controller within a different or the default area:

Multiple types were found that match the controller named XXXXXXXX...

I thought it was a little cheap of Microsoft requiring you to give your controllers unique names across all areas. I was relieved to find out giving the same name within different areas is perfectly OK, you just need to specify the full namespace for the controller when setting up the route for it, like so:

public override void RegisterArea(AreaRegistrationContext context)
{
 context.MapRoute(
  "Members_default",
  "Members/{controller}/{action}/{id}",
  new { controller = "Home", action = "Index", id = UrlParameter.Optional },
  new string[] { "MyWebApp.Areas.Members.Controllers" }
 );
}

I knew Microsoft wouldn't let me down ;)

Friday, 18 June 2010

Mock ControllerContexts in ASP.Net MVC

After performing an upgrade to MVC 2 for a web application last week, I had a number of tests failing. This gave me an opportunity to refactor some controller tests and create a base class for my controller test classes. This new base class is straight forward and allows me to mock HttpRequestBase and HttpSessionStateBase easily on the mock ControllerContext - it also has an overload for mocking AJAX requests too. I expect this class to grow in time but it serves my needs for now:

public class TestController
{
 public static ControllerContext GetMockControllerContext()
 {
  return GetMockControllerContext("GET", false, null, null);
 }

 public static ControllerContext GetMockControllerContext(string httpMethod, bool isAjaxRequest)
 {
  return GetMockControllerContext(httpMethod, isAjaxRequest, null, null);
 }

 public static ControllerContext GetMockControllerContext(Mock httpRequestBase, Mock httpSessionStateBase)
 {
  return GetMockControllerContext("GET", false, httpRequestBase, httpSessionStateBase);
 }

 public static ControllerContext GetMockControllerContext(string httpMethod, bool isAjaxRequest, Mock httpRequestBase, Mock httpSessionStateBase)
 {
  var headerCollection = new NameValueCollection();

  // Add header value for ajax requests
  if (isAjaxRequest) headerCollection.Add("X-Requested-With", "XMLHttpRequest");

  if (httpRequestBase == null)
  {
   httpRequestBase = new Mock();
   httpRequestBase.Setup(r => r.HttpMethod).Returns(httpMethod);
   httpRequestBase.Setup(r => r.Headers).Returns(headerCollection);
   httpRequestBase.Setup(r => r.Form).Returns(new NameValueCollection());
   httpRequestBase.Setup(r => r.QueryString).Returns(new NameValueCollection());
  }

  if (httpSessionStateBase == null)
  {
   httpSessionStateBase = new Mock();
  }

  var mockHttpContext = new Mock();
  mockHttpContext.Setup(c => c.Request).Returns(httpRequestBase.Object);
  mockHttpContext.SetupGet(c => c.Session).Returns(httpSessionStateBase.Object);

  return new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock().Object);
 }
}

Friday, 11 June 2010

Time to Upgrade to ASP.Net MVC Web Apps to MVC 2?

Wondering if you should be upgrading to ASP.Net MVC 2? It is worth some serious thought as there's some powerful new features, the upgrade process is nice and simple, plus there aren't many breaking code changes. Why not take a peek at what's new in ASP.Net MVC 2 and I bet you'll see at least a handful of features that'll get you itching to upgrade ;)

If you decide to upgrade your web application then review the MVC 2 upgrade notes. They include instructions for upgrading manually or you can choose to use the upgrade tool. I've used the upgrade tool and it seems to work great for most people - but not me, I had two problems :( After the conversion completed I compiled my project and got an error:

It is an error to use a section registered as allowDefinition='MachineToApplication' ...

...I managed to fix this without pulling my hair out though. The only other issue I had was around 10% of my project tests suddenly started failing; a result of some change to the controller context processing (this resulted in me improving my controller tests by creating a base TestController). Again this was a nuisance rather than a show stopper - the upgrade was worth the effort :)

Thursday, 10 June 2010

IIS 6 Application Pools for Beginners

Application pools allow you to configure one or more web applications to a worker process. An application pool is separated from other application pools by worker process boundaries. So what does this mean? ...An application in one application pool is not affected by problems caused by applications in other application pools. This along with sensible recycling of your application pools, results in your web server being more efficient and reliable.

By default IIS 6 dumps everything into one application pool. So as you add new web applications to your server you should consider logically grouping them into pools. Due to there being an overhead for each application pool it makes more sense to group the web applications into related pools rather than just create a pool for each web application.

Recycling Your Application Pools

To keep your sites working efficiently your should configure IIS to periodically recycle your application pools and recycle them when they become unstable (using too much memory/cpu etc). Recycling cleans up memory fragmentation, memory leaks, abandoned threads and other bits of unwanted clutter. Note that when an application pool recycles, ASP.Net session state information stored in-process is lost for that pool, however other pools are not affected. If this is a problem then you'll need to use another session state mechanism for your ASP.Net web applications.

Application Pool Recycling Events

It's important that you review why your application pools are being recycling. For example, if you have a pool recycling every 30 mins due to excessive memory use then you have an issue with that applcation's code and it needs looking at. Event logs for application pools are off by default, to enable them see this Microsoft KB article.

Security

When you configuring your application pools you can configure the identity of each worker process to run as a different user and should consider how to configure application pools for application security. For example, you might need to create separate application pools for applications that require a high level of security, while allowing applications that require a lower level of security to share the same application pool.

Convinced?

Hopefully with this post you can see the benefits of spending some time in setting up your application pools in IIS and you've made a step in the right direction for improving your web server's reliablility and efficiency :)

Wednesday, 9 June 2010

ASP.Net allowDefinition='MachineToApplication' Error

I've come across this problem a number of times now and it was beginning to annoy me. A few times when building projects on continuous integration servers and today when upgrading my MVC web app to MVC 2 I hit the following error:

It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level This error can be caused by a virtual directory not being configured as an application in IIS.

Everytime I failed to figure out what the problem was and instead I had to admit defeat and use a work-around :(

Well the error message is quite helpful for some people getting this error at runtime and tells them how to fix the problem - configure the web apps virtual directory to be an application. However, I'd been stumbling upon this delightful error when compiling projects - not at runtime!

Luckily I had a light bulb moment... the compiler was not referring to my main web.config for the application, but instead was moaning about a web.config within a sub directory of my application (a backup of the project). Deleting the backup sub directory solved my problems!

I got 99 problems but my web.config ain't one!

Tuesday, 8 June 2010

Handling Unexpected Exceptions in ASP.Net MVC

There are way too many yellow screens of death out there on the net for my liking. But rather than trying to bullet proof your MVC web apps by putting try catch blocks in all your MVC actions to handle unexpected exceptions, there is a far easier way to do it and it keeps your code nice and DRY - see my code snippet below:

public class BaseController : Controller
{
 
 protected override void OnException(ExceptionContext filterContext)
 {
  // Record the error
  Log.Error("Unexpected error in controller", filterContext.Exception);

  // Uses customErrors element from web.config
  if (filterContext.HttpContext.IsCustomErrorEnabled)
  {
   // Set exception as handled and status code 500
   filterContext.ExceptionHandled = true;
   filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

   this.View("Error").ExecuteResult(this.ControllerContext);
  }
 }

}

I override the OnException method within a base controller for my other controllers to inherit from. Any unhandled exceptions in my action methods will hit this and I can gracefully log the exceptions and send the user to a helpful error view (as long as customErrors for the app are set to true) - it's worth noting I also set an appropriate HTTP status code :)

Thursday, 27 May 2010

Multiline Comments in Powershell

It's hard to believe but you can't do multiline comments in Powershell for some reason! Shame on you Microsoft! Here is a bit of a hack to allow you to right comments over multiple lines using a multiline string declaration:

@'
This is a hack so
you can do a multiline
comment in powershell
'@ > $null

Points to note...

  • The closing '@ has to be in column 0
  • No whitespace allowed after the opening @'
  • Redirect the output (or cast to [void]) unless you want to see it on the console or in a log file

Wednesday, 26 May 2010

Internet Explorer 5.5 / 6 PNG Issues

Most web developers are aware of the IE alpha transparency problems with PNG images; or will be before long. A lot of developers use GIF images rather than the superior PNG format for this reason; which is a shame.

I was discussing the issue with Alex over at Prettier Pixels (a talented UK freelance website designer and builder) and he suggested this nifty IE PNG fix by TwinHelix that you can use to avoid the issues. Thanks Alex!

I long for the day when IE 6 support is no longer required!