Scott Hanselman

Deploying ASP.NET MVC on ASP.NET 2.0

July 8, '08 Comments [24] Posted in ASP.NET | ASP.NET MVC
Sponsored By

minefieldThis post will be filled with disclaimers and warnings. They are not just to CYA, but also to C my A and avoid my getting sacked.

I've been working with Shawn Burke and Rob Conery and the magical Eilon Lipton to try to figure out a way to get ASP.NET MVC running under ASP.NET 2.0 SP1. Shawn had this idea and told Rob "go figure this out." Rob was really busy doing the MVC Storefront so he told me "go figure this out, you like this kind of freaky stuff."

Take a moment to look at my post on How to set an IIS Application or AppPool to use ASP.NET 3.5 rather than 2.0 for background on the physical relationship between .NET 2.0 and .NET 3.5.  There's a lot of stuff going on between 2.0 and 3.5, even though the CLR is more or less the same.

I was brainstorming ways to get ASP.NET MVC running on a .NET 2.0 machine and there were a couple of ways. I could recompile/fork all the stuff at http://www.codeplex.net/aspnet and compile via #ifdefs or manually an ASP.NET 2.0  version. However, then I'd have to maintain multiple versions, it could get really messy really quick.

I ended up speaking to Brad Abrams and spent the last few weeks, on and off, talking to all the different groups that owned different parts of the framework. I expressed that I could get a Hello World ASP.NET MVC application working if I:

  • Developed on Visual Studio 2008
  • Targeted .NET 2.0 in Project Properties
  • Deployed the Application to a .NET 2.0 SP1 machine
  • Copied System.Core.dll local to the web apps /bin folder

It's that final step that we're not technically allowed to do, but I'm showing you how to do it in case you real;y want to ASP.NET MVC on a machine that you just can't put .NET 3.5 on yet.

Here's the disclaimers:

  1. This workaround is offered with exactly zero warranty or support. It's as-is, just an FYI on the blog. If this hack deletes files or kills your cat, you have been warned. No whining.
  2. In practice, no one really knows what might break.  Microsoft didn't test this.
  3. You must not redistribute System.Core.dll to a 3rd party. You mustn't bundle it or ship it with your application.
  4. When you update to .NET 3.5, remove your local copy of System.Core.dll
  5. Don't GAC System.Core.dll.
  6. Don't taunt System.Core.dll.
  7. Take a moment and read #3 again.
  8. This just flat might not work for you. Sorry.
  9. Don't do this to any machine that you don't own.
  10. I wanted to have an even ten, so this is a placeholder disclaimer in case I forgot one.

After all those sunny disclaimers, I do hope that this helps someone in some small way to get a development site running on .NET 2.0 while you prepare for an upgrade to .NET 3.5.

What To Do

From an ASP.NET MVC Web Application, you'll need to set your Project Target Framework to 2.0 in Project Properties:

image

NOTE: This doesn't enable all of 3.5, or even much of .NET 3.5. But it does enable System.Web.Mvc and it's supporting assemblies to run as they are the ones with the reference to System.Core. However, remember, at this point, you and your project are living in .NET 2.0 world.

Running 2.0 means you don't have LINQ to SQL or Entity Framework or anything. You'll need to use something else. In my example code I'm using Davy Brion's NHibernate Northwind Sample as it's a .NET 2.0 compiled solution and it'll be acting as my Model.

VS 2008 Will Try to Stop You

When you add references to System.Web.Routing, System.Web.Abstractions and System.Web.MVC you'll get warnings like this one. Click Yes. This is VS trying (rightfully) to protect you from confusion and assembly errors as we'll see, and if you click "yes" you're saying you really know what you're doing. From this point on, we're on our own.

image

After this, you can develop your now .NET 2.0 application as you like, using 2.0 technologies. Some of the cooler ASP.NET MVC stuff won't work, particularly in the Views if you try to use lambdas with HtmlHelpers or use the var keyword. This is because while your development machine's compiler is 3.5 since you're using VS2008, when you deploy your ASPX views to the server side, that machine has only .NET 2.0 SP1 and will compile those views with the 2.0 compilers.

For example, this line of code in a view that showed a list of products...

<% foreach (var product in ViewData.Model) { %>

...gave me this error.

CS0246: The type or namespace name 'var' could not be found (are you missing a using directive or an assembly reference?)

If you see errors like this, you'll know you're using 3.5isms that's not understood by the 2.0 compiler in your Views.

Deploying to an ASP.NET Machine

Since I'll be deploying on a machine with .NET 2.0 SP1, I'll use an XP SP2 Virtual Machine running IIS6. You can find a fantastic troubleshooting blog post by Omar Al Zabir on Deploying ASP.NET MVC on IIS 6 here. Suffice it to say, my routes use the .mvc extension, and I've associated .mvc with aspnet_isapi in the IIS6 management console.

I've also updated my routes to include the .mvc extension so IIS6 can "see" the requests:

routes.MapRoute("mvcroute", "{controller}.mvc/{action}/{id}"
    , new { controller="products", action = "Index", id = "" }
    , new { controller=@"[^\.]*"});

ASIDE: If you like, you can certainly enable pretty URLs using ISAPI_Rewrite and remapping requests to extensionless URLs to .mvc or you can configure IIS6 with a wildcard map. I prefer the former.

image

After I deploy my ASP.NET MVC application over to my .NET 2.0 SP1 machine, again, in this case running IIS6, I might see this YSOD indicating I don't have System.Core on that machine. This makes sense because this machine doesn't have .NET 3.5 installed.

Here's the moment of truth, and the moment we step from supported to unsupported. You can copy System.Core from your .NET 3.5 development machine (this is the machine running VS2008 that you're developing on) to the /bin folder on your .NET 2.0 SP1 machine. It's gotta be running .NET Framework 2.0 SP1 or this won't work.

image

System.Core is probably somewhere around "C:\windows\assembly\GAC_MSIL\System.Core\3.5.0.0__b77a5c561934e089" on your machine, but you're a bad person for even asking.

image

Copy that file into your bin folder on your deployment machine and you should be able to Refresh past this error page.

Things You Don't Get With This Hack

  • Support from Me or Microsoft (in that order)
  • Any .NET 3.5 feature like LINQ to SQL or LINQ to Entities
  • Many of the HtmlHelpers and cool things that work with Lambdas won't work with inline script in Views because those pages will be compiled on the server using the 2.0 compiler.
  • Good karma

Things You Appear to Get With This Hack

  • ASP.NET MVC seems to work
  • Anything you can do in ordinarily in .NET 2.0 works
  • Bragging rights
  • A spot on your immortal soul
  • The ability to show your boss that ASP.NET MVC is a good thing, and maybe get him/her to let you upgrade the server to ASP.NET 3.5 with the promise of even cooler stuff.

I was able to get a full Northwind Sample Site up using ASP.NET MVC Preview 3 with NHibernate against the Northwind Database in about two hours. This was my first NHibernate application of any size and I'm sure I did it wrong, but it works on my machine! Thanks again to Davy Brion's most excellent and thoughtful example, it was a great way for me to learn NHibernate (which has a bit of a learning curve).

image

Navigating Microsoft Legal

One thing that I wanted to add was that this was my first time navigating Microsoft Legal. I was dreading it. However, the LCA (Legal and Corporate Affairs) guy that helped me through it was exceedingly cool. Rather than what I expected - here's reasons why you CAN'T do this - he was more like, "what can we do to make this happen." I don't know if it's representative of Microsoft Legal in general, our division, or just this nice guy, but either way, it was cool and he's my go-to guy the next time I try something crazy.

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Tuesday, July 08, 2008 8:22:13 PM UTC
Glad you're giving NHibernate a try. :)
Tuesday, July 08, 2008 8:25:17 PM UTC
glad you liked the nhibernate example :)

keep in mind that it only shows pretty basic CRUD usage though... there's a lot of querying goodness in nhibernate that is sadly lacking in my sample. Definitely worth looking into ;)
Tuesday, July 08, 2008 8:39:09 PM UTC
You are a star!
Tuesday, July 08, 2008 9:05:07 PM UTC
FYI Dave's link is broken in the article...I'll find it elsewhere here I'm sure.

Ryan
Tuesday, July 08, 2008 9:26:16 PM UTC
Scott Hanselman
Tuesday, July 08, 2008 10:37:12 PM UTC
Nice hack. Will the anonymous types and collection initializers work though? Or, is that the point of having System.Core.dll?

Eddy.
Tuesday, July 08, 2008 11:00:52 PM UTC
Will it be possible to recompile and redistribute a version of MVC that's bound to LINQBridge instead of System.Core?
Tuesday, July 08, 2008 11:11:58 PM UTC
Duncan - I'll ask. The issue is more System.Web.Abstractions and System.Web.Routing. You can at least try!
Scott Hanselman
Wednesday, July 09, 2008 12:15:19 AM UTC
I tried something similar just for grins about a month ago. I figured since the runtime hasn't changed since 2.0, there really wasn't any reason something compiled with 3.5 wouldn't work as long as all of its dependencies were present. So, just to see what would happen I created a web application with lambdas, Linq, extension methods, and all kinds of other post-2.0 goodness then deployed it to a Win2K server with IIS6 and .NET 2.0 framework. I went through a cycle of "run -> add assembly it's bitching about to bin -> re-run" until it finally fired up and ran! The web application project was precompiled, so it didn't JIT and run into compiler issues.

Obviously not something someone would want to do for anything important, but it was a fun excercise.
Jamie
Wednesday, July 09, 2008 7:36:56 AM UTC
How would you stand legally if trying to deploy to a Linux/Apache/Mono server? Would it be any different to a standard Windows/IIS/ASP.Net 2.0 server? Currently they claim to be somewhere "between .NET 2.0 and .NET 3.5" whatever that means - I'm guessing that it means a website targeting .NET 3.5 wouldn't work, although I've not tried it yet.
Giraffe
Wednesday, July 09, 2008 7:38:51 AM UTC
I'm using ASP.NET MVC in an ASP.NET 2.0 web site, just for the TempDataDictionary. It works great (I don't need System.Core for this scenario) but I still have a problem I hop you can help me with it.

Each time I compile or run (ctrl-f5 ) the web site I get a warning from Visual Studio. Where can I turn that off?

Thanks!

PS. TempDataDictionary could just move to System.Web and be a part of ASP.NET WebForms too if you ask me. System.Web.UI.Page and others could have a TempData property just like MVC views.
Mikael
Wednesday, July 09, 2008 9:26:11 AM UTC
Rob was really busy doing the MVC Storefront so he told me "go figure this out, you like this kind of freaky stuff."

So true -- and an excellent post, too. :)
Wednesday, July 09, 2008 11:42:28 AM UTC
Really good (and a bit shamanic) post.

But it really strikes me as absurd, in a real environment, that the IT Management of your Company would let you develop an ASP.NET MVC application and then forbid you to install the 3.5 Framework (or to create new virtual servers where you can install it).
Wednesday, July 09, 2008 12:59:28 PM UTC
Scott, you rock.

Incidentally, the tab order for that OpenID box is messed up, I would expect it to go through the other boxes (name, email, homepage) and then come to the 'type here' box. It just goes to the top of the page.
Wednesday, July 09, 2008 2:27:42 PM UTC
Why go through all the MS Legal b.s. when you could just recommend either one of Mono's System.Core.dll or LinqBridge ?

I have been using Mono's System.Core.dll with great success on 2.0. And if i want linq to xml, I pull in Mono's System.Xml.Core and System.Xml.Linq, and I think I needed a 3.5 version of System.Xml, so I removed the MS one from my project and used the Mono System.Xml. That is a bit extreme on the XML side, I'll admit, but those XML Literals in VB.NET are just so tempting!

Wednesday, July 09, 2008 2:28:02 PM UTC
With all due respect, I don't know that you can make many comments regarding good karma or spots on your immortal soul while posting screenshots of yourself using IE6. :)

Other than that, keep kicking ass. I'm using MVC a lot at work lately and loving it. Coming from a rails background to a .net shop was soul crushing until I discovered the ASP MVC project. Looking forward to the IronRuby team helping to bring all the new hotness together in dynamic happy fun time.
Wednesday, July 09, 2008 6:20:54 PM UTC
Way to protect yourself! :) Here is your disclaimer: http://blog.quantumbitdesigns.com/2008/07/08/blogs-can-destroy-your-house/
Wednesday, July 09, 2008 7:29:27 PM UTC
And this hack works for 3.0 too?
DanH
Wednesday, July 09, 2008 8:19:48 PM UTC
This is the error I keep getting everytime I run (ctrl-f5). It makes it so annoying that I can't really use it, because I can't find a way to turn this error off.

---------------------------
Microsoft Visual Studio
---------------------------
The .NET Framework version required by assembly 'System.Web.Mvc.dll' or one of its dependencies is higher than the project target .NET Framework version.
Do you want to add this reference to your project anyway?
---------------------------
Yes No
---------------------------
M
Wednesday, July 09, 2008 9:17:31 PM UTC
In general I have found that legal guys won't tell you what you can or can't do... but rather they will tell you if you have a defensible position. Always come prepared with things like "I want to do X", not "What can I do based on our legal agreement?"
Thursday, July 10, 2008 1:01:45 AM UTC
I have a site in production using MVC in ASP.NET 2.0.

I recompiled System.Web.Routing.dll and System.Web.Abstractions.dll and removed all dependencies on System.Core.dll...

So because I didn't redistribute System.Core.dll, am I ok from the legal side?
anonymous
Thursday, July 10, 2008 8:22:00 PM UTC
I don't like Haacks (no pun intended Phil ;) ). I prefer a final launch of ASP.NET MVC.

When, Scott, when? :(
Thursday, July 10, 2008 8:38:58 PM UTC
Andrei - I suspect it will release in a month that ends in "-ber"

Anonymous - I'm not sure. Where did you get the code for Web.Routing and Web.Abstractions?
Thursday, August 28, 2008 11:31:59 AM UTC
This is really petty, I know, but I can't help myself :-)

You have written "Here's the disclaimers" which would expand to "Here is the disclaimers". Obviously this should be "Here are the disclaimers" so you should have shortened it to "Here're the disclaimers" or "Here's the disclaimer list".

Sorry :-)
Nony Mouse
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.