ASP.NET MVC3 系列教程 - 如何使项目Debug进MVC3源代码
I:关于如何Debug进MVC3源代码.
1.关于ASP.NET MVC3的源代码获取方法
ASP.NET MVC从1.0到3.0版本以来它的源代码是完全对外开放的,也正因为这个原因吸引了不少以前习惯使用WebForm的开发人员转向研究MVC,在这里也很”高兴”各位IT业界内的朋友们不断地向MS反馈信息..才有了今天的MVC3版本号的出现..也不知下一个版本会.......
转回原题它的源代码托管在微软的codeplex上,下面的连接为ASP.NET MVC的项目地址,大家可以很方便地获取到它:
http://aspnet.codeplex.com/wikipage?title=MVC&referringTitle=Home
下载下来以后.我们查看一下源代码包内的各各MVC部件的分布情况:
MVC3源代码包文件名为:mvc3-rtm-sources.zip
下面一图介绍了MVC3中最主要的几个程序集在源代码包中的具体位置
2.下面开始介绍如何创建一个可Debug进MVC3源代码的Visual Studio MVC项目
首先我们从VS2010新建一个空白的解决方案dotNetDR_MVC3_ExampleProject,然后在VS中关掉这个解决方案,接着把解决方案文件复制到
mvc3-rtm-sources文件夹(也就是你解压MVC3源代码文件出来的那个位置,在这里我的路径比较长.我的位置是:
D:\SVN_WorkFolder\dotNetDR\Project\Code\mvc3-rtm-sources,各位朋友请根据自身实际情况进行相关操作).
然后依次添加如下MVC项目文件到我们所建立的空白解决方案当中,并且执行编译,最终的解决方案资源管理器图为:
在此我电脑上面编译期间一路顺风顺水!无Error无Warning!~_~....
接着我们建立一个名为WebApp的解决方案文件夹然后添加一个名为MVC3_App1的新建MVC3项目.然后移除原来从GAC内引用过来的MVC3程序集,再添加引用本解决方案内当中的各个MVC3项目:
最后Mvc3_App1的情况为:
接着Web项目编译是完成的.但是你运行的话就悲剧了.因为本地程序集和GAC的程序集冲突了.
[A]System.Web.WebPages.Razor.Configuration.HostSection cannot be cast to [B]System.Web.WebPages.Razor.Configuration.HostSection. Type A originates from 'System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll'. Type B originates from 'System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\7c2060f6\6145b34e\assembly\dl3\9036b7c7\fc8023c0_73fecb01\System.Web.WebPages.Razor.DLL'.
之前我曾有过卸载掉在GAC当中的MVC3程序集的想法,但最终因该程序集和Microsoft Windows Installer有关联而无法用gacutil /uf来卸只能另寻其他办法.
最后几经折腾,终于明白了引起冲突的具体原因:
幸亏之前的做法尝试失败,真正的原因其实还是因为在Web Pages 1.0中他在web.config内新增了一个配置节点,我目前可以肯定的是开发人员可以根据需要而取消掉默认MVC3配置环境就在这个新增的节点当中.当然这要求开发人员比较深入地了解MVC3才行
Web Pages 1.0在Web.config中目前我已发现到新增了一个配置节点:
路径在~/Views/web.config.而不是web.config.至于web.config能否使用?还有待研究.
<configuration> <system.web.webPages.razor /> <!--注意他于常用的system.web同级--> <system.web /> ... </configuration>
关于这个配置节点的说明目前我还没找到MSDN上有具体的英文介绍.而只是能找到相关的类库成员列表.而详细的介绍说明还未完善.还得等待MS的文档工作人员完善.~
接着我们可以打开他并修改相关的PublicKeyToken为null.设置可以让.NET Runtime引用我们解决方案中的未签名MVC3源代码项目而非用GAC当中引用.这样的话可以解决掉之前出现的同名类型在不同的程序集中发生冲突的可能性.~这个特性也是.NET相比以前的XX(冒似是COM+这类,作者不太了解那个年代的东西)改进了同名不同版本的类库冲突
下面进行修改我们的MVC3_App1项目内的~/Views/web.config文件
<xml version="1.0"> <configuration> <configSections> <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"><!--这行要改--> <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" requirePermission="false" /><!--这行要改--> <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" requirePermission="false" /><!--这行要改--> </sectionGroup> </configSections> <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null" /> <!--这行要改--> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> </namespaces> </pages> </system.web.webPages.razor> ...
接着修改~/web.config文件
<configuration> <connectionStrings /> <appSettings> <add key="webpages:Version" value="1.0.0.0"/> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings> <system.web> <compilation debug="true" targetFramework="4.0"> <assemblies> <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <!--这行要改--> <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null" /> <!--这行要改--> <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </assemblies> </compilation> ... </system.web> ... </configuration>
在这里我发现了有一处硬编码了这个PublicKeyToken的地方:
位于项目System.Web.WebPages.Deployment中的PreApplicationStartCode.cs文件Line 24:
待我深入了解好了.在向各位解释这个常量的作用
修改完成以后我们设置相关断点
断点1放置位置 at System.Web.WebPages.Deployment项目根目录内PreApplicationStartCode.cs Line:39
断点2放置位置 at Mvc3_App1项目Controllers文件夹下的HomeController.cs Line:12
再按F5去Debug一下MVC3_App1项目接着就可以顺利地debug进去了.
上图为App初始化时走的流程,我以前写的文章有介绍过WebPages脱离WebForms的运行方式,有兴趣的可以去回顾一下那篇文章.
上图可以看到运行点已经到达了Action内了.这说明我们离成功非常接近了.
直接运行下去,看到了这一个蓝页已证明我们引用的所有MVC源程序已经可以正常工作了,此时的你是否与博主一样激动呢?
经过这一折腾,这一章节就算顺利完成了,同时也为往后要了解MVC3内部工作原理开了一扇窗.