Using the ASP.NET MVC source code to debug your app
MVC February 3rd, 2009Most ASP.NET MVC developers know that the framework source code is available. This means you can:
- Read the source code to see how things work
- Edit, compile, and use your own custom build with your own modifications (though this is almost certainly not necessary, as the framework gives you plenty of extensibility options)
Instead of just reading the MVC Framework source code in the abstract, one of the best ways of understanding what’s going on is to put it directly into your application’s solution. You can include the System.Web.Mvc C# project in your solution (as if you created it!), and then handily step into and out of its code while debugging, or use Visual Studio’s Go to Declaration command (or ReSharper’s) to navigate from your framework class references directly into the source. Personally, I find this very useful.
Attaching the System.Web.Mvc source code to your solution
Here’s how to include the System.Web.Mvc project source in your solution:
- Download the ASP.NET MVC source code from CodePlex (be sure to get the version that corresponds to whatever version of ASP.NET MVC your app already uses). Extract the ZIP file to some convenient location.
- Add System.Web.Mvc as an existing project. In Visual Studio, open your existing application, then go to File –> Add –> Existing Project. Find and select System.Web.Mvc.csproj, which will be in the source code you just extracted from the ZIP file, probably in the MVC\src\SystemWebMvc subdirectory. You’ll now have System.Web.Mvc in Solution Explorer:
- Remove your app’s existing reference to System.Web.Mvc. Just find it in the list of references, right-click it, and choose Remove.
This eliminates the reference to the GAC version of System.Web.Mvc (the one that was registered when you first installed ASP.NET MVC). - Add a project reference to the source code version of System.Web.Mvc. Right-click on your app in Solution Explorer, choose Add Reference, go to the Projects tab, and select System.Web.Mvc.
That’s it! You can now compile and run your application, and you’ll have a live reference to the framework source code, so you can step in and out of it, and can jump directly from any reference in your own source code to the corresponding point in the System.Web.Mvc source code. This can make debugging much easier.
Stop being so ambiguous!
Actually, there is a bit of a snag. If you have view pages without code-behind files (which is the default, since the Release Candidate), then when you try to run your app, you’ll get the following error:
You’ve now got one self-compiled instance of System.Web.Mvc.dll in your application’s \bin folder, plus the official original copy in your GAC from when you first installed ASP.NET MVC. So how is the framework supposed to decide which one to use?
Well, the only reason it considers the GAC version is that your web.config file tells it to. Go and edit your web.config file and comment out the System.Web.Mvc GAC-version reference:
Now it will only consider the version in your \bin folder, so the ambiguity ("Parser Error”) will go away.
Update: Wait, there’s more! Another config change you need to make - if you want to run a custom build of ASP.NET MVC - is in /Views/web.config (note: that’s not your top-level web.config). Since the RC, strongly-typed views depend on a clever page parser filter. Find this string:
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
… and change it to:
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
That just tells the page compiler that it can use your custom build of ViewTypeParserFilter (and that it doesn’t have to use the GAC version). If you don’t, then strongly-typed views will throw the error “‘object’ does not contain a definition for ‘YourModelType‘”.
What about deployment?
When you come to deploy your app to another server, remember that your web.config file now doesn’t reference the GAC version of System.Web.Mvc, and the rest of your code is compiled against your custom build. To make it work on another server, you can either:
- Deploy your custom build of ASP.NET MVC in the \bin folder. Your custom build of the assembly will already be in your \bin folder, so this is what will happen automatically.
- Reverse the steps you just took above (which means manually editing your app’s .csproj file to reintroduce a reference to the GAC version of System.Web.Mvc, rather than the project reference). You could probably make this part of your automated build process.
I have found this technique extremely useful when trying to understand what the MVC Framework is actually doing with my application.


February 3rd, 2009 at 3:04 pm
Great tip
February 3rd, 2009 at 7:30 pm
What do you think of just having the .pdb file of the mvc lib instead of including the actual source project of it for debugging? That way you can still debug into the source and you don’t have to include another lib in your solution.
February 4th, 2009 at 6:09 pm
Nice post, Will try this out
February 4th, 2009 at 8:45 pm
I tried this and it is working fine for pages that don’t use strongly typed views. But I created a strongly typed view and it is telling me the following:
CS1061: ‘object’ does not contain a definition for ‘FooDogInt’ and no extension method ‘FooDogInt’ accepting a first argument of type ‘object’ could be found (are you missing a using directive or an assembly reference?)
So it is apparently trying to treat the model as an instance of Object…though it obviously isn’t. Did you not run into this?
February 5th, 2009 at 8:01 am
@Eric - aha, thanks for pointing that out! That’s a new behaviour in the RC that sneaked past me.
I’ve updated this blog post (see the “Update: Wait, there’s more!” segment above), explaining another config tweak that’s now required.
February 24th, 2009 at 7:16 pm
[…] Then Steve will help you solve the ambiguous reference problem. […]
March 26th, 2009 at 8:12 am
Hi! dude
good application.
May 11th, 2009 at 12:14 pm
This can also occur if you add a standard master page and then attempt to switch the inherits tag to “System.Web.MVC.ViewMasterPage” after it created the code behind files for the standard master page (even if you remove the codebehind tag). I ended up deleting the code behind and designer files, then recompile and everyting works.
Interesting info tho.
June 1st, 2009 at 10:21 am
I am new to MVC and learning it from different website thanks
July 7th, 2009 at 2:21 am
Thank you for this tip. Very helpful!
July 8th, 2009 at 10:39 am
Any idea why this is not working? I can’t compile my app (it has multiple projects - is this a problem?). I’m getting “The type ‘System.Web.Mvc.Controller’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′.
September 21st, 2009 at 6:31 pm
Very useful, Steve! (As is your book.)
Anyone been successful getting MVC 1.0 source debugging to work in VS 2010 on .NET 4 target? I tried and am getting security rule exceptions on GetObjectData() even though my controllers don’t implement GetObjectData() (just use base Controller implementation). Perhaps subtle differences between .NET 3.5 and 4 security causing these problems?
-Andy
P.S. Similar security rule issues reported on this string http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=464751
System.TypeLoadException was unhandled by user code
Message=Inheritance security rules violated while overriding member: ‘System.Web.Mvc.TempDataDictionary.System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)’. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
Source=System.Web.Mvc
TypeName=System.Web.Mvc.TempDataDictionary.System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)
StackTrace:
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) in C:\mydocs\Visual Studio 10\Projects\GroupDat\Source\SystemWebMvc-10Src\Mvc\ControllerBase.cs:line 76
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) in C:\mydocs\Visual Studio 10\Projects\GroupDat\Source\SystemWebMvc-10Src\Mvc\ControllerBase.cs:line 87
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) in C:\mydocs\Visual Studio 10\Projects\GroupDat\Source\SystemWebMvc-10Src\Mvc\MvcHandler.cs:line 89
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) in C:\mydocs\Visual Studio 10\Projects\GroupDat\Source\SystemWebMvc-10Src\Mvc\MvcHandler.cs:line 68
at System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) in C:\mydocs\Visual Studio 10\Projects\GroupDat\Source\SystemWebMvc-10Src\Mvc\MvcHandler.cs:line 104
at System.Web.Mvc.MvcHttpHandler.VerifyAndProcessRequest(IHttpHandler httpHandler, HttpContextBase httpContext) in C:\mydocs\Visual Studio 10\Projects\GroupDat\Source\SystemWebMvc-10Src\Mvc\MvcHttpHandler.cs:line 12
at System.Web.Routing.UrlRoutingHandler.ProcessRequest(HttpContextBase httpContext)
at System.Web.Routing.UrlRoutingHandler.ProcessRequest(HttpContext httpContext)
at System.Web.Routing.UrlRoutingHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext context)
at MvcApp._Default.Page_Load(Object sender, EventArgs e) in C:\mydocs\Visual Studio 10\Projects\GroupDat\Source\MvcApp\Default.aspx.cs:line 18
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:
September 28th, 2009 at 8:51 am
Using the ASP.NET MVC source code to debug your app « Steve Sanderson’s blog…
Thank you for submitting this cool story - Trackback from Servefault.com…
October 15th, 2009 at 4:55 pm
Nice post!
It’s working perfectly event with MVC2-preview1-sourceCode!
Reshaper pointed me to 2 more web.config keys that need to be set to null.
pageBaseType=”System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null”
userControlBaseType=”System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null”>
October 19th, 2009 at 8:47 am
[…] If you want to step through the source code using your application I refer you to Steve Sanderson’s excellent blog post. […]
December 16th, 2009 at 2:20 pm
Many Thanks! been trying to figure out what part of the MVC magic I was doing wrong, banging head against desk for hours. This is now letting my find what I’ve done wrong, instead of trying to guess!
February 10th, 2010 at 1:34 am
Hi Steve,
Can this be done even in projects that reference other third party assemblies (say, Telerik.Web.Mvc) which in turn reference MVC2?
I’ve done the setup according to your instructions, but when I try to compile I get compilation errors like:
“Error 49 The type ‘System.Web.Mvc.IActionFilter’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′.”
It seems like my third party assemblies aren’t aware of the System.Web.Mvc project? Or is the problem that they rely on a specific PublicKeyToken?