Integrating ASP.NET MVC into an existing ASP.NET Webforms application

If, like me you’re not always blessed with the opportunity to build every application from scratch, you may find yourself wanting to introduce the wholesome goodness of ASP.NET MVC into an existing ‘classic’ ASP.NET Webforms application. Most tutorials out there concentrate on nice green field development.

What follows is largely a reference for me to remember how to do this.  It’s basically a matter of manually injecting what the project templates do for a new application.  I’m also not professing to have come up with all of these steps – I’m just bringing them together.

I’ll assume you’ve got all the necessary prerequisites (MVC 4.0) installed already, and if you have a web ‘site’ project, then I’d suggest you update it to a web application before doing all of this.

Getting the structure and configuration to look like MVC

There’s a number of standard folders, and bits of code you’ll find dotted around MVC applications – Models/Views/Controller for instance :)

The following article goes through the first steps of getting those folders into your project (assuming you don’t have a naming conflict).

Mixing ASP.NET WebForms and ASP.NET MVC

Updating to MVC4

This is all good, but that article’s a bit old, and you’ll find the next one brings you (mostly) up to date with MVC 4.0

Adding MVC 4.0 to WebForms Project

If you want to use any of the newer features such as bundling, or if you’ve copied some views from an MVC4 project into your new MVC project, you’ll need the ASP.NET Web Optimization Framework (get it from NuGet).

You may also want to take an MVC4 project and convert the global.asax code to call off to the classes in the App_Start folder…

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }
    }

Getting the Visual Studio MVC Template Goodness

This is great, but the icing on the cake is to make Visual Studio think this is an MVC project, so you get the nice right-click options, like add–>Controller if you’re in the controllers folder.  It turns out you just need to fool Visual Studio by adding a project type guid in your web projects csproj file…

With Visual Studio I just did a quick diff between a new MVC 4 project’s project file, and my ‘hybrid’ project’s file.

The following is what you’re looking for…


<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{18BBC72C-702B-40CD-B347-D7FC66D276FA}</ProjectGuid>
<ProjectTypeGuids>{E3E379DF-F4C6-4180-9B81-6769533ABE47};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

If you just add the first ‘ProjectTypeGuids’ guid to the corresponding place in your project file, and reload, the magic happens, and Visual Studio thinks it’s now an MVC project.  You’ll probably find you already had the other 2 guids.

NDepend – Visual Studio Addin: takes you as far as you want to go

First of all I’d like to point out that I was kindly given a license by the folks at NDepend (not very often that sort of thing happens I can assure you!) and I’m under absolutely no obligation to write anything about it.

In the beginning…

The funny thing is that it was probably over a year ago when I first installed the product without any specific requirement or
expectation. I had a little play with it (on Visual Studio 2008 as I recall), then the work I ‘had’ to do overtook my will to learn this new product and it lay gathering dust on my hard drive.  This probably explains why I haven’t posted in all that time!

But then…

Recently, I picked up an existing project (on visual Studio 2010), and wanted to have a good look inside to see what I was getting myself into. I dusted off NDepend and told myself I’d give it a good go this time…

First Impressions

The first thing I learned is that this is one significant addin, and you realistically need to ‘know you need it’ before you get it (see ‘laying
dormant comment above’). This also means you need to know what it can do for you – which is plenty!

If you’re reading this and thinking of trialling NDepend, then you either have problems to solve or you’re wanting to invest in ongoing improvement to your code. Both are very good reasons as it happens.

NDepend has few limitations in what it can do, as it has your entire codebase, Visual Studio extensibility and its own powerful rules engine at its disposal. It also employs its own CQL (code query language), to allow you to find all sorts of patterns and complexity problems with your code.

The biggest problem is knowing where to start, or discovering that first task you want to achieve with it. It’s easy to get overwhelmed by the
information it bombards you with when you spin it up).

To be fair, there’s plenty of links trying to lead you to ‘what you’re looking at is…’

Reasons to try/buy

If you’re interested in the quality of your code I believe there really is no equal.  This is the tool you need. You may already be using FX Cop in your build process to check for certain snytactical rules, and ReSharper for sorting out your code as you go, but NDepend can do all sorts of ‘different’ funky stuff (through CQL) that goes in depth to your code to enforce things that would be otherwise difficult to do It can obviously do all the simple stuff like show you where your dependencies are between methods, classes and projects, and redundant code etc.

Some highlights I quite like – made possible through CQL:

  • Enforcing of layering constraints – i.e. ‘this UI project cannot directly reference ‘that’ ‘DAL’ project
  • Simple spot check stuff like queries on a ‘lines of code’ threshold – indicating complexity
  • Code not meeting an acceptable test coverage
  • For all the possibilities you’ll need to look here.

Things to be aware of

  • It’s a technical tool, and it’s easy to get a little overwhelmed with what it can do and where to start.
  • Time is needed to understand some of the concepts and power of the product.
  • You’ll need a beefy machine to avoid things slowing down with the addin loaded (I had to disable it for a while when I was using a solution with 60 projects as I was starting to experience memory issues).  If you don’t want to run it in Visual Studio, you can run it in the standalone ‘Visual NDepend’ application.
  • I’ll admit I haven’t spent a lot of time with the interactive reports, and I don’t find some of the graphical representations of the metrics that easy to use.
  • I think like most products, you get comfortable with what you see as valuable, and tend to only try other things when you have time.

Summary

Clearly NDepend’s a very impressive tool for any serious development team to be using. It will help you to learn about reducing complexity, dependencies and generally designing your code in an efficient way. It’s basically all about improving quality.

It’s also a big product that’s not for the faint hearted. You basically get out what you put in as far as effort in understanding what it’s trying to achieve for you.

I think the key is finding the right balance between all the technical information it presents, the time you have available, and the business benefit you’ll get from code improvements.

As I said at the start. It can basically take you as far as ‘you’ want to go.

Worth taking a look at: http://www.ndepend.com/

How to generate a list of Visual Studio Shortcuts

I’d seen addins that list Visual Studio shortcuts before, but seem to have lost them.  I also used to use ReSharper, so memorised its shortcuts.  I’m now back to ‘naked’ Visual Studio, so am having to re-learn the standard shortcuts.

I was surprised to find this article on MSDN that has code for a macro to produce a html page of all the shortcuts.  Just run the macro, open it up and search in the browser whenever you’re having problems remembering – unless you really want to print it (in which case I’d be inclined to bang a bit of CSS in there :) ).  I might improve upon the whole situation if I find myself needing to refer to it more often, and will post updates here.

Visual Studio Documentation – Have your say

Brad A’s just been highlighting the MSDN Survey to get opinions on how Visual Studio and MSDN documentation works (or doesn’t) for people.  I added my 2c and it made me think a little about how I access ‘help’ these days.  Here’s what I wrote in the ‘other comments’ (Q 14 I think).


I generally access MSDN content through google (as it’s quicker than accessing the MSDN site, waiting for it to load the TOC, then searching).  It’s probably testament to the indexing of the site that a search such as “msdn Path.Combine” will take me straight to the specific page I ‘know’ I’m looking for.  I guess this means I’ve got some knowledge of how things are structured and I use that to good effect.  In a simple comparison…


Local Help
Typing Path.Combine into VS.NET code editor – selecting the text and hitting F1 came up with a false start (my current machine doesn’t even have the docs installed apart from Enterprise Library 3.1.  It did find some less than useful reference from EntLib!).  I went to Help options and chose ‘use online first’, and tried again (incidentally I didn’t even realise you could pull in your own list of sites to search (Codezone community) – cool).  It chose a different ‘Path property’ first and took about a minute in total to get to the right ‘Path class’.


MSDN Library Site
Opening up the MSDN site (which still feels too heavy in my book – and now curiously like BBC news) and searching for ‘Path.Combine’ took about the same time (1 min).  This includes opening the browser, loading up the MSDN home page, searching, clicking the first item in the search results, and loading that page.


Google search on MSDN
Opening up Google (admittedly my home page – but I’m looking for speed here) and searching for ‘msdn Path.Combine’ took 20 seconds.  The first item in the list was what I wanted so got straight to it.  It’s also worth noting that Google’s become a little fat puppy too with all my iGoogle stuff on it, but it’s still way quicker than any of the alternatives.


 

Getting the most out of ASP.NET Web Deployment Projects

In my ongoing love (but mostly) hate relationship with ASP.NET Web ‘Site’s’ I’ve been using Web Deployment projects to make things more bearable. 


I currently swap in connection strings from 3 files – one for each build configuration (debug, test, release – connectionstrings.debug.config etc ).  This works fine as per the doco on WDP.  I use CruiseControl.NET and NAnt to automate builds, and a few nagging ‘automated’ pieces were missing from the puzzle. 



  1. Encryption of connectionStrings (or other web.config sections that you want to protect) – without affecting the ‘source’ file.  I’ve assumed here that ‘internal’ people are trusted. 
  2. Changing of other config stuff (like debug=false) in the test and release builds.  (My attempts to get this to work had previously failed as you don’t seem to be able to specify system.web as a replaceable section.
  3. Encrypting Forms authentication passwords, using MD5 hash.  This isn’t difficult, I just didn’t have a tool to generate the hash value.

Encryption of config sections


OK – after re-reading Scott Gu’s post on Web Deployment Projects, and K. Scott Allen’s post on how to simply encrypt sections of config files, I realised that I could just add a post-build event (manually) in the wdproj file (right-click in solution explorer –> open project file). 


The build events are already in but commented at the bottom of the file.  I ended up with

<Target Name=”AfterBuild”>
<Exec WorkingDirectory=”$(OutputPath)” 
Command=”C:\windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef connectionStrings .”
/>
<!– Also remove our ‘source’ config files using the del command rather than the delete task as you
have to jump through hoops to specify wildcards –>
<Exec WorkingDirectory=”$(OutputPath)” Command=”del compilation*.config” />
<Exec WorkingDirectory=”$(OutputPath)” Command=”del connectionstrings*.config” />

</Target>


If I put this anywhere other than ‘AfterBuild’ it didn’t seem to do anything.  I certainly learnt a bit more about aspnet_regiis, as I’d only used it previously to ‘install’ ASP.NET.  I also had to specify the path to aspnet_regiis, but you could obviously use a property for this (I’m new to MSBuild – only dipping in when I have to, so the framework path may already be a standard property?).


Replacement of system.web sections


The key thing here (which I don’t believe was documented very well anywhere) is how to replace system.web elements.  Other typical replacements – e.g. appSettings or connectionStrings are children of the root config element.  You’d therefore assume that you need to replace the whole of system.web (which is a little inconvenient – but still worth it).  This doesn’t work and you’ll get a ‘nice’ WDP00002 error saying it can’t find the system.web element (a bit like saying ‘can’t find printer’ when it’s right next to the computer!). 


You just have to go one level down as follows (in the Deployment –> Web.config file section replacements property page):


system.web/compilation=compilation.release.config


compilation.release.config may be as simple as…

<compilation debug=”false”></compilation>

You might have a warning saying ‘compilation’ isn’t a valid element, but this is just the intellisense barking as it validates against the config schema.


Encrypting Forms Authentication Passwords


This is pretty simple and there’s lots of docs to support this, but I wanted a simple tool to generate the hash for a given string, and a quick google yielded a nice little command-line tool


This way you can plug it into your build if you need to, but also replace for different environments using the techniques above.


ASP.NET Web Site Project (WSP) vs Web Application Project (WAP)

ASP.NET 2.0 originally came without support for the ‘traditional’ Web Application project that everyone had become familiar with in ASP.NET 1/1.1.  Some people liked the new approach as it affords more ‘on-the-fly’ updates, but obviously enough people ‘didn’t’ for Microsoft to release a patch for Visual Studio .NET 2005 to allow creation of WAP’s.  The support was then formally re-added in VS 2005 SP1 (making the original patch redundant).


Info on the situation can be found here.


This post (as well as saving the links for me) is also a reminder of the limitations of the Web ‘Site’ model (hereafter known as WSP) and why I choose not to use it.



  • Namespaces.  WSP does not explicitly add a namespace to any page, class etc.  It uses ‘special folders’ with some implied names (e.g. App_Code) to determine the namespace hierarchy.  This whole situation can also lead to strange ‘circular reference’ errors with user controls – especially after converting from VS 2003.  At the very least you’ll be pulling your hair out wondering why you can’t reference some page or control from somewhere else in your site.
  • Code Reuse.  Only code in the App_Code folder (and below) can actually be referenced by another class in the project.  This forces a structure that you wouldn’t otherwise choose.  You can of course create separate assemblies – and should in many cases.
  • Unit Testing support in VS 2005.  WSP does not build to a single assembly when built in VS 2005, and must be ‘precompiled’ using a Web Deployment Project which in turn uses the asp_merge (publish) utility in order to achieve this.  The standard publish function doesn’t support a single assembly, although it’s possible to get the App_Code into a single DLL. This all means that because you don’t have an output at build time, you can’t run unit tests in the WSP – regardless of how much code you’re ‘reusing’ in the App_Code project.  You can jump through some hoops to call the NUnit Console runner, but why bother!?   
  • Included/Excluded files.  Because WSP doesn’t have the concept of a project file to say what’s ‘in’ and what’s ‘out’, VS 2005 uses a rather nasty ‘rename’ method of excluding files – simply suffixing the file with .exclude to denote it should be disregarded.
  • References are actually just copied in.  If you create a reference to an external assembly, VS 2005 will actually just copy the file into your bin folder.  This means you’ll end up putting all sorts of binaries in your source tree (under source control), that you maybe otherwise wouldn’t
  • Automated Build.  NAnt and other automated build tools can’t work out whether a Web Site project is some sort of ‘enterprise template’ project, or a tub of lard – because it’s not really a project.  This means that you can’t use the <solution> task with NAnt.  you have to call a custom <exec> task instead, calling the asp_merge.exe tool, then call all other projects separately too.  This all works, but again, why bother?  A cynic might conclude MS was trying to cause issues for NAnt, whilst getting people interested in MSBuild.

For me, any change that introduces new ‘non-standard’ tools, just so you can have the convenience of ‘on-the-fly’ updates just isn’t worth it.  You’ll actually find that this all goes out the window when you deploy to a server anyway, because depending on how you ran asp_merge, you probably won’t be able to do any ‘real’ updates because the assembly names are generated in that process and you’ll break the site by changing source files.  In my opinion if you are using this approach then use the Web Deployment project and build to a single assembly to minimse these issues.  If you’ve got any sort of structure around your production deployments (and you can’t just ‘copy over’) then I see literally no advantage in the WSP model, as it just seems to provide too much pain for no visible gain.

Free Visual Studio 2005 Addins

I’m currently without ReSharper (eek), so am trying to make the best of it.  Looking around for VS 2005 addins (that I haven’t already got), I stumbled across a few resources….


Carl J has a list of Free Addins, and, wait – there’s another list


Not forgetting Hanselman’s (old) list


I’m sure there’s more, but I don’t want to overcapitalise and slow my machine down more than Resharper did (maybe I should look at CodeRush?)