Asp.Net网站的的编译与发布原理
如下所示创建一个简单的asp.Net Web应用程序
在VS中生成解决方案之后,可以在项目的目录下看到以下的文件:
当我们通过VS将网站发布出去之后,可以看到,最后生成的文件,如下图所示:
我们可以发现,发布之后的项目文件夹内少了很多文件,其实这是VS将aspx页面和一般处理程序以及Global文件等的后台文件都编译成了一个dll文件,这个dll文件存放在bin文件夹内:
对这个程序集进行反编译之后,可以看到我们写的后台代码都编译到这个dll文件中了
这个是一般处理程序的ProcessRequest方法中的代码,可以看到就是我们写的源代码:
此时项目文件夹内的几个文件中只剩下一些简单的声明了,所有后台代码都已经不见了:
Global文件:
一般处理程序:
aspx页面:
然后我们通过以下这句代码分别获得页面,一般处理程序以及Global编译运行时所在的位置:
System.Reflection.Assembly.GetExecutingAssembly().Location
经过对比可以发现Global文件、一般处理程序、aspx后台代码所在的程序集文件为同一个,而aspx前台页面的代码运行在另一个程序集中,以下为运行的结果:
Global和aspx页面的前台与后台运行文件:
一般处理程序的后台代码:
我们可以看到IIS运行网站时,实际将网站编译之后的dll文件都放到了对应的Framework版本中的临时文件夹中了
即在C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files下,网站中自己写的后台代码与类库以及引用的类库都被编译到了这个临时文件夹下当前项目所在的文件夹下的assembly文件下。
网站发布后的文件分布图:
此时对比发布的网站根目录下的bin文件夹里的dll文件和一般处理程序运行时所在的程序集,可以发现两者是同一个文件:
此时如果删除网站根目录先的bin文件夹内的dll,然后再浏览页面内,可以发现网站无法正常运行:
由上面的结果可以看出,虽然网站中已经存在了一个后台代码的dll文件,但是网站实际运行的是系统文件夹中的那个dll文件,这个应该是直接从网站中拷贝过去的,它们的MD5值完全相同。
在这里可以推测,对于asp.Net应用程序来说,IIS只会编译aspx页面,一般处理程序,Global等文件,但是不会编译其他的类文件,所有的类文件对IIS来说没有用处,IIS只能使用编译好的dll文件。
当网站正在运行时,无法删除系统文件夹中的那个dll文件,显示被IIS Worker Process占用,这个更加说明网站实际运行时使用的是这个dll文件
那么这个IIS Worker Process进程是什么呢,当我们结束当前网站对应的w3wp.exe进程时,系统文件夹中dll被成功删除,这个可以说明,这个dll的调用者正是w3wp.exe这个进行,也说明了w3wp.exe是网站的工作进程。
当我们删除系统文件夹中的dll文件时,再次访问网站时会重新在系统文件夹中再次生成dll文件,而且第一次访问时候报错:
再次访问就正常了
总结:
所以可以总结出,在IIS中运行asp.Net应用程序时,前台页面的代码是即时进行更新和编译的,当我们修改前台代码时,不需要重新编译项目或者重新发布网站,在访问网站时,IIS(或者.Net框架?)检测到页面发生了修改会帮我们重新编译页面,而在修改了后台代码和其他的类文件的时候就需要我们手动对源代码进行重新编译了。
以上的内容都是针对Asp.Net应用程序来说的
对于Asp.Net网站来说发布网站时不会将页面和一般处理程序以及其他一些代码编译成dll文件,只会将源文件和引用的一些类库拷贝到网站的目录下,对于解决方案中的其他类库,也会在编译好之后再拷贝到Bin文件夹中。
在这里可以推测,在asp.Net网站中,IIS或者其他的程序,在有人第一次访问网站时,将App_Code文件里的源代码编译成了dll程序集
当用户第一次请求时才进行即时编译,编译好的文件也是存在于系统文件夹下
如:C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\7812c4be\73872874
此时生成的文件有以下这些:
直接在VS中调试时,情况与上述在IIS中运行类似,只是最后所在的文件目录有所不同,而且会生成很多调试用的文件:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\website1\0e58724c\a4f149c8
总结:
Web应用程序和Web网站的前台页面的代码都是在网站运行时,被初次访问时进行编译的,而对于后台代码和网站中的一些类文件来说,Web网站也会在网站第一次被访问的时候被编译,所以,Web网站中的后台代码更改后不需要手动进行编译,而在Web应用程序中,后台代码和类文件都会在发布的时候进行编译,编译成功才能够正常发布,所以对于Web应用程序,修改了后台代码就必须重新编译然后发布。
注:网站编译的临时目录可以在IIS中或者Web.config配置文件中进行配置,一下是IIS中的修改方法:
在服务器级或者网站级的".Net编译"选项中修改编译的临时目录,默认情况下临时目录为网站对应的.Net Framework的版本下的Temporary ASP.NET Files文件夹。
作者: 陌上荼靡