Archive for category Software Development

Handling multiple Web.config files in Visual Studio

I use different settings for my application when it is running on the live server and when it is running on my development machine. To manage this I name my config files using the target name like so:

  • Web.Debug.config
  • Web.Release.config

Adding the following to the project file will cause MSBuild to automatically copy the correct file to ‘Web.config’ when you build the project in Visual Studio. In my case the ‘BeforeBuild’ target was already in the project file but commented out, I just needed to add the copy task and related items.

<Target Name="BeforeBuild">
   <ItemGroup>
   <ConfigSourceFiles Include="Web.$(Configuration).config" />
   <ConfigDestinationFiles Include="Web.config" />
   </ItemGroup>
   <Copy
      SourceFiles="@(ConfigSourceFiles)"
      DestinationFiles="@(ConfigDestinationFiles)"
   />
</Target>

So I select the right target from the toolbar and build/publish and the correct settings are used.

Where possible, to avoid duplicating settings, I create separate config files and point the main config files at it using the configSource attribute. For example the page settings for debug and release are the same so my pages element in both files look like this:

   <pages configSource="Configuration\System.Web\pages.config" />

Before implementing this I was manually changing or copying the config files before deploying to my server, so I hope this will help someone else save a bit of time.

Tags: , ,

Not mocking the HttpContext?

Someone asked me a question recently about mocking, and I had to say I didn’t have much experience with it. I found this answer a bit odd myself as I’ve been doing a lot of TDD with an ASP.Net MVC application. I’d seen lots of people talking about mocking the HttpContext and wondered “Why haven’t I had to do this?”.

The first time I started TDD, I was working on converting an existing ASP.Net application to ASP.Net MVC. Most of my controller actions checked the current security principle in the context, so I immediately ran into problems when trying to test these.
I didn’t know much about MVC or TDD so used what I did know. I knew about a powerful component of MVC called an action invoker, that could be overridden to handle some parameter stuff. I found that I could easily create an ActionInvoker that would populate parameters of a certain type (namely IPrincipal) using the following code:
public class ActionInvoker : ControllerActionInvoker
{
   protected override object GetParameterValue(System.Reflection.ParameterInfo parameterInfo)
   {
      if (parameterInfo.ParameterType == typeof(IPrincipal))
         return HttpContext.Current.User;

      return base.GetParameterValue(parameterInfo);
   }
}

And put the following into my controller constructors:
public MyController()
{
   ActionInvoker = new ActionInvokers.ActionInvoker();
}
This made it easy to test my controller actions. I just needed to mock a simple IPrincipal. I used a similar solution when my file upload controller needed access to HttpContext.Current.Request.Files.
At the moment my code only depends on a few simple objects that come from the HttpContext and not the context itself. Surely this is better, if not please comment. I’m going to change the above to conform with everyone else by mocking the HttpContext but the only reason I see for doing this, is that the above action invoker is not testable. Is this the only reason?
Before you point it out to me, I have recently moved most of my security code into AuthorizeAttributes. Now my unit tests for invalid calls (security wise) to controller actions all fail but that’s for a future post.

Tags: , ,

What's up with the Tadmap project?

If you’ve been following the Tadmap blog then you might be wondering why there haven’t been any updates since November. Well here’s why.

Before Christmas I decided to try out the new ASP.Net MVC framework, for no other reason than wanting to learn more about it. My initial impression was that it would be ideal for Tadmap, so I decided to go for it. The change over meant refactoring all the pages I already had into controller and views, and I got 90% there very quickley. As I had never used MVC before I started following Rob Conery’s MVC Storefront series to make sure I was doing things right. This may or may not have been a mistake.

First, he was using a fancy new version of the Repository pattern which I liked the look of very much, this lead to even more refactoring and learning more about LINQ on the way.

I tried to ignore the Test Driven Development aspect of what Rob was doing, but eventually I downloaded Nunit just to try my hands at writing an automated test. Straight away I was hooked on TDD. I tried limiting TDD to just new code but to make the new code testable meant refactoring the old code to reduce dependencies.

It’s taken a lot longer then I wanted but I am having a lot of fun doing it. My code is clean and loosely coupled and I have over a hundred unit tests and a bunch of integration tests that I can fire with one click.

Even though I have no boss and as yet no users, I have still run into the age old problem of doing it right versus getting it done. There is the ultimate balance to be made between making things perfect while achieving the goals and real world features that help our moral and motivation. It’s starting to bother me that I haven’t been able to add any new features in over a month.

So in the next few weeks I hope to get an, albeit imperfect, ASP.Net MVC version of the application up on the live server. I’ll then be in a position to iron out the last few post refactoring bugs or implement a cool new feature when I need the motivation to keep going.

Tags: , , ,

ASP.Net MVC on Blacknight

Update: SP1 is now installed for ASP.Net 3.5. So now the only DLL you need to upload is ‘System.Web.Mvc.dll’.

I was reading a little bit about the new ASP.Net MVC stuff. I think it would be ideal for my Tadmap (image hosting) project. Before I started any major development re-work I needed to check that my hosting provider, Blacknight, could host it.
So I uploaded the sample MVC application. Of course it didn’t work at first but I don’t give up that easily and it is now up and running. I think the following steps will work for anybody else trying the same.
As Blacknight do not have SP1 installed for ASP.Net 3.5 you have to upload the new DLLs when you deploy. Simple instructions can be found here, Bin Deploying ASP.NET MVC.

My windows account on Blacknight is using IIS 6.0 which does not automatically support MVC. In order to handle URLs the MVC way you will need to follow the instructions here, ASP.NET MVC on IIS 6 Walkthrough. Basically, you just need to grab the code for the Global.asax.cs file and add a ‘.mvc’ file mapping using your Blacknight control panel.
To add the file mapping, just go to the ‘Web’ tab of your domain and add ‘mvc’ to the ASP.Net 2 mappings. It should look like the image below and make sure that ‘Script Engine’ is ‘On’ and ‘Verify File Exists’ is ‘Off’.

One small (cosmetic) problem is that the URLs aren’t as clean as they should be because the ‘mvc’ extension is needed. So the URL for the About action of the Home controller that should look like ‘http://trevorpower.com/Home/About‘ instead looks like ‘http://trevorpower.com/Home.mvc/About‘. I have seen solutions to this problem as well but that’s for another day. Right now I have the not so small task of converting an existing ASP.Net application to an ASP.Net MVC application.

Tags: , ,

Tadmap – Image Hosting for Map Collectors

One of my interests is in early maps. I don’t have a big collection or anything but I would like to be able to browse them on my computer or show them to other people. One of my hobby projects is to provide a website that does just that.

The technical aspects of developing Tadmap I will probably write about on this blog, but I am also writing on the Tadmap blog if you are interested in learning more about it.

Tags: , ,

No WWW

I have never really thought about it before, but I hardly ever type ‘WWW’ into an address bar. Out of habit I skip this part of any URL. It has never caused me any problems till this week, for one of my own websites.

As I’ve said in an earlier post, I have added OpenID support to one of my websites. I used the DotNetOpenId library. This library made the development very easy and was up and running in no time on my development machine. But recently I have published the website to a live server and things haven’t been going that smoothly.

When a user provides an OpenID the url they entered must be stored on your server while the client is directed to the third party OpenID provider. This is to do with the fact that the url might redirect to another url/provider for authentication and in this case the original ulr/id may not come back when authenticated. To store the original url on the server I just bunged it into the session (I believe this is standard practice). However when I tested it on the live server I would always get an error because the session would be empty.
I then noticed that if from the error page, I try to log in again it would succeed. Eventually I figured out what was going on. The return address I was providing was of the form ‘www.mysite.com’ while I always typed ‘mysite.com’ when testing. Switching from the non ‘WWW’ version to the ‘WWW’ version of the url caused the session to be cleared.
Another problem is that when being authenticated by an OpenID provider, the relying party must provide a ‘realm’ that the user is authenticated for. The realm is basically the domain of the relying party website. The problem is that ‘www.mysite.com’ is not considered part of the ‘mysite.com’ realm.

This means that to keep things simple I had to decide which address I was going to use and redirect one to the other. The choice was made simple because no-www.org had some good arguments and the yes-www.org website was down (or maybe I forgot the www). 

Redirecting turned out to be easier than I thought (I didn’t need to contact hosting provider). I just added a ‘.htaccess‘ file to the root of my directory with the following lines

RewriteEngine OnRewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

This tip I got from no-www.org.

Tags: ,

Source control for Visual Studio Express

I use Visual Studio full time in work so it is an obvious choice as an IDE at home as well. As none of my hobby projects are revenue generating and are quite small, the Express (free) editions of Visual Studio are another obvious choice. I have been using the Web Developer, C#, SQL versions of Visual Studio Express and find them sufficient for my small to medium projects.
The express editions are very limiting when it comes to plugins and extensions so a lot of the tools and extras that I am used to are not available. However the only thing I ever really miss is source control. Every experienced developer knows how important it is to have their source code under some sort of source control. For now I am the only developer, but I still like to know what I have changed and be able to revert files back to a previous state. The other thing you take for granted when you have source control (in normal multi developer environment) is the automatic backup and duplication of code on to another machine (which is usually backed up off site).
In the past I have used Visual Source Safe, Perforce and Team Systems and first looked at these as a solution. Of the three, only Perforce offers a free license (for two users). I installed the Perforce server and the P4V client (which I had used before). So I added my source code directory and started coding. The P4V client was a bit awkward to use and it didn’t pick up file changes automatically. It was technically usable, but I ended up not using it properly, just doing an arbitrary weekly check-in.

Now I had some form of basic revision history and rollback facilities but I was not happy with my back up system, which was to backup every thing onto a CD tomorrow. The simple solution for this is a third party to host my source control database. There are a few websites that provided this service for free but most are only available for Open Source projects. A few commercial services do offer a limited service for free and I went with Unfuddle who provide free Subversion hosting (size limited). So I signed up, created a repository and tried a few clients.
The minute I started using the TortoiseSVN client I was very impressed. It has all the functions you would expect from a version control system (see screenshot), but as part of your normal file explorer. It picked up changes in files automatically and was a pleasure to use. Straight away I started doing more regular change related submits. And now I have peace of mind that my source code is backed up off site.

Tags: , , , ,

My Globe

The links on this post are no longer valid. I hope to post on this topic again in the future.

I’m trying to overlay Google Earth with a pair old maps.

The latest Google Earth has a very simple overlay tool. You just select an image and drag/stretch it over the correct area. The hard part is making sure the image is of the correct projection, Plate Carrée, otherwise stuff gets squished together at the poles.

The maps I’ve started with have the equator as a circle on the outside of and the pole is a single point in the middle. This means I cannot just place them as is, if you overlay an image on to a pole it shrinks to nothing. The maps I have are in a Stereographic Projection so I wrote a simple application to convert these to the correct projection. The resulting image looked like this.

The writing in both maps is north-up and parallel to the lines of latitude. This means that when wrapped around a sphere it should make a nice north up globe.

You can download the result here. (You must have Google Earth 4.2 or above)

This is my first attempt. There are a couple of improvements I intend to make.

  • Even though the maps are small and zooming will be of little benefit, the resolution could be better.
  • The lines of latitude on my the original maps do not line up with those provided by Google earth.
  • The is a problem with distortion around the seems that is not on the image so they are caused by Google earth.

Tags: ,