ASP.NET MVC项目部署与IIS版本变化介绍

开发 后端
本文从IIS以及asp.net与IIS相关的部分的角度讲解了asp.net mvc项目的部署问题。文中还介绍了一些与IIS版本变化有关的资讯。

asp.net mvc 1.0正式发布至今已将近四个月了,想必了解asp.net mvc的人越来越多。打算写一点关于如何部署asp.net mvc的文字。

内容包括:IIS的版本变化,asp.net的工作原理等。

涉及的东西比较基础,内容也比较多,肯定会有我们已经知道的东西,但是为了完整性,可能会分(一)、(二)……如果你对asp.net不太熟悉的话,可能阅读中会遇到一些理解不了的地方,在这些地方我会给出推荐您阅读的书籍或者园友的文章供你参考,如果你是asp.net高级开发人员的话可以略过。

主要参考资料:Pro asp.net mvc Framework.pdf(你可以搜索下载到)

部署,就是将你的网站发布到服务器上以使人们可以实际使用。如果你曾经部署过asp.net项目的话,你将会发现部署asp.net mvc实际上跟部署 asp.net差不多,唯一特殊的地方是asp.net mvc使用到了Routing,可能有人尝试过在IIS6上使用无后缀URL的方法,如果你知道了下面这些列出的内容的话,就会变得很容易了。

asp.net mvc宿主服务器所需的条件。

IIS处理请求的架构,路由是如何与之融为一体的。

安装IIS6和7到Windows服务器,将asp.net mvc项目部署在他们上。

配置你的asp.net mvc项目。

该篇包含前两个内容

ASP.NET MVC项目部署之服务器环境

要运行asp.net mvc项目,我们的服务器需要满足如下条件:

 IIS5.1或者更高版本的IIS,并且开启了asp.net服务。

 .NET Framework 3.5(***同时安装了SP1)

推荐的操作系统是Windows server 2003(IIS6)和Windows server 2008(IIS7)。asp.net mvc本身不要求服务器必须安装了它。因为我们将System.Web.mvc.dll和你或许用到的Microsoft.Web.mvc.dll直接放在\Bin文件夹中部署就可以了,这种部署方式叫做私有部署,如果你买的空间没有安装asp.net mvc的话(即GAC中没有上述的两个dll)通过私有部署的方式也很容易,另外如果你的服务器没有安装过.NET Framework SP1的话,你还需要将System.Web.Abstractions.dll和System.Web.Routing.dll也拷贝到你的\Bin文件夹中。下面会详述这些。

asp.net mvc对我们买的虚拟服务器有什么样的要求

除了需要服务器支持asp.net 2.0和安装了.NET Frameworkd 3.5之外没有其他要求。所以我们看不到有空间提供商打广告说自己的空间支持asp.net mvc,因为通过把相关的程序集放在\Bin文件夹中你同样可以私有部署你的asp.net mvc项目。

如果你的服务器提供商用的是IIS7,那么IIS7与asp.net的集成管线模式可以给你带来干净的无后缀的URL,如果是IIS6的话虽然也能够做到,但是就没有IIS7那么高效、方便和容易了,下文会有关于Windows server 2003/IIS6的内容。

关于IIS版本变化

 IIS6/ Windows Server 2003。

 IIS7/Windows Server 2008。

 IIS 7.5/Windows Server 2008 R2(尚未发布)。

我们仅仅介绍6.0之后版本的IIS,下面我们来快速覆盖一下IIS的知识,包括:虚拟路径、绑定设置和应用程序池。***谈一下IIS内部是如何处理请求的(IIS7是如何处理无后缀的URL的)。

理解网站和虚拟目录

IIS可以同时宿主多个不同的网站,我们对每一个网站指定一个根目录,这个目录可以是服务器的本机目录也可以在网络的其他地方,然后IIS就可以从它所管理的那些目录下寻找或获得相应静态或动态请求的内容给我们了。

为了指导特定的HTTP请求到相应的相应网站,IIS允许我们配置“绑定”。所谓“绑定”就是将一个特定的IP、TCP端口号、和HTTP主机名对应到特定的网站。如下图:

说明:Windows7/IIS7.5 

作为一个额外的配置,你还可以在网站目录文件夹任意层级上添加虚拟目录,每一个虚拟目录表示IIS将从其他地方提取或获得内容返回给对该虚拟目录的请求,这取决于你建立的虚拟目录所指定的文件夹的位置(它同样可以在本机也可以在网络的其他地方)。虚拟目录的目的是让真实文件所在的位置与网站目录列表脱离关系,有点类似文件夹的“快捷方式”,虚拟目录的存在使得外界不知道我们的真实文件所在具体位置,个人感觉逻辑上的意义大于安全上的意义。

说明:IIS7/IIS7.5中虚拟目录的显示 

说明:IIS7/IIS7.5中虚拟目录的显示

对于每一个虚拟目录你还可以选择是否赋予它独立的应用程序地位。如果选择这样做,该虚拟目录对应的独立的应用程序就拥有自己独立的配置文件了,如果该独立的应用程序是个asp.net应用程序的话,那么它的状态也是独立的啦,是与它的父级应用程序的状态无关的。显然,因为他们是相互独立的应用程序,所以被设置成独立的应用程序的这个虚拟目录中所运行的asp.net完全可以是和父级不同的版本的asp.net。

从IIS6开始,IIS引入了应用程序池(application pools)。应用程序池用来隔离同一台服务器上的多个同时运行的应用程序,每一个应用程序池工作在一个独立的工作进程中,设定相应的***内存和CPU使用量,进程回收时间表,等。每一个网站或设置为独立应用程序的虚拟目录应用程序都会被分配到建立起来的IIS的应用程序池的其中一个池中去。一般的话,每个应用程序应建立一个应用程序池而不是与其他应用程序共用。这样可以保证如果一个应用程序崩溃了不影响其他应用程序的正常运行。参考:应用程序池

绑定网站到主机名、IP地址和端口

因为同一个服务器可以宿主多个网站,所以就需要一个系统来分派请求到正确的Web应用程序。上文提到,我们可以绑定网站到一个或者多个:

端口号

主机名

IP地址(仅当服务器有多个IP地址时——比如有多个网络适配器)

对于主机名和IP地址,你可以选择不做任何指定,不做任何指定等于是一个通配符,这样的话对于所有不匹配特定网站的请求就会匹配给它。如果多个网站具有相同的绑定设置的话,同一时间只可能有一个是可用的,其它的处于停掉的状态,否则就不唯一了,对吧。虚拟目录继承父级应用程序的绑定设置。

IIS是如何处理进来的请求并调用asp.net的

当IIS将接收到的一个请求分配给相应的网站的时候,它需要决定怎么来处理这个请求。它是要直接从磁盘返回一个静态内容呢,还是要调用网站应用程序执行它并动态地生成内容来返回呢?它是如何决定这些的?

作为一个asp.net mvc程序域,你需要理解IIS的这个机制,不仅是asp.net mvc程序员,asp.net程序员都需要理解这个机制(asp.net程序员包含asp.net mvc程序员)——至少应该有个基本了解;否则,你将会在理解进来的请求与你的路由配置映射时遇到困难。

IIS版本变化:IIS6和IIS7在传统模式下是如何处理请求的

如果你没有使用IIS7的集成管线模式的话,你使用的将是回归到IIS5的传统管道模型。在这个模式下,IIS只能提供静态内容和具有特定扩展名的从而可以映射到相应的ISAPI的URL返回的动态内容。

IIS分析请求近来的URL,取得它的扩展名(比如:http://hostname/folder/file.aspx?foo=bar的扩展名是.aspx),将该扩展名发往相应的ISAPI扩展程序。对于IIS6和IIS7来说,你都可以配置ISAPI扩展程序与扩展名的映射,对于IIS7来说,你还可以使用处理器映射配置工具(装的不是中文版IIS翻译不准,英文为Handler Mappings configuration tool),如下图所示。

说明:Windows7/IIS7.5 

说明:Windows7/IIS7.5

上图中*.aspx被配置给了aspnet_isapi.dll,aspnent_isapi.dll这个非托管的dll在操作系统启动时就已经被IIS加载到了内存中,该dll与托管环境进行交互然后将控制权转交给该应用程序所在的隔离的应用程序域的.NET CLR,CLR接到控制权后,接着实例化一个HttpRuntime类对象,然后调用该HttpRuntime实例对象的ProcessRequest方法从而驱动后续的处理,当ProcessRequest执行结束的时候封装请求上下文信息的Datacontext实例就被构建完成了,继续,进入asp.net运行时管道(可能叫做管线会更好些,MSDN上翻译的是管线),这个管道就像是条工厂中车间的流水线,而这条流水线上加工的对象就是前面HttpRuntime实例化出来的那个封装请求上下文信息的DataContext实例对象,每个HTTP模块和管道后端的HTTP处理程序都是一道加工工序,这些工序有的负责验证权限,有的负责asp.net的状态管理等,我把这个过程不确定的归结为职责链模式(C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG路径下< httpModules>节点中注册了这些默认的HTTP模块),接下来就是在管道中按照HTTP模块注册的顺序挨个执行各个HTTP模块,***到达管道尾端的HTTP处理程序,比如我们的Page类就是一个实现了IHttpHandler接口的处理程序。再往下就是控件以及页面生命周期等这些我们非常熟悉的东西了。值得说明的是,在我们的Global.asax中从System.Web.HttpApplication类继承而来的那个自定义类中按照约定的方式书写代码就是我们与所有这些Http模块们交互的方式了。其实对于System.Web.UI.Page的实例化实际上是通过工厂来返回的,上图注册*.aspx的时候就是注册到了默认的PageHandlerFactory工厂了,该工厂实例再根据前面所有那些步骤中一直存在的***封装到了DataContext中的请求的URL对应的文件名来查找相应文件名的的真实的.aspx文件,并读取该文件的***行指令,指令指定了最终负责处理该请求的HTTP处理程序类,这个类就是我们编写的 System.Web.UI.Page类(一般是从Page继承过来的子类)。接下来服务器控件与组件以及页面的执行最终生成HTML页面内容,生成的HTML结果返回给开始的aspnet_isapi扩展***被IIS输出。而控件以及页面生命周期等这些已经是我们非常熟悉的领域了。有兴趣的话你可以翻阅MSDN或者觉得有什么意义的话更进一步用Reflector沿着流程从System.Web.UI.PageHandlerFactory开始查看源代码。

说明:Http模块就是实现了IHttpModule接口的类,Http处理程序就是实现了IHttpHandler接口的类。老赵说过:如果你不理解Http模块和Http处理程序的话就不能称为真正熟悉asp.net,之所以要理解HttpModule和HttpHandler是因为理解了他们之后才能明明白白地基于HttpModule和HttpHandler进行编程,扩展我们的asp.net应用程序管线中的内容(原话可能不是这样,意思应该是这样)。如果你想了解HttpModule和HttpHandler的话,有两本书非常值得推荐:微软出版社的《asp.net 3.5技术内幕》和Wrox的《asp.net 2.0服务器控件与组件高级编程》这两本书的相关章节都有对该主题较好的介绍。阅读小洋(燕洋天工作室)的浅谈asp.net内部机制系列或者张子阳的关于asp.net的文章也是一个不错的选择。asp.net mvc在HttpModule和HttpHandler级别上与原来的asp.net是完全一样的。

asp.net是如何被关联的

在你安装.NET Framework的时候(或者执行aspnet_regiis.exe的时候),安装程序自动注册了*.aspx,*.axd,*.ashx,和其他一些扩展名到一个特殊的名字叫做aspnet_isapi.dll的ISAPI扩展程序。一个请求必须与一个注册过的扩展名相匹配,然后IIS将激活aspnet_isapi.dll,这个非托管的dll再把控制权转交给托管代码,接下来就是托管代码的时间了,.NET CLR在一个不同的进程中执行这些接下来的非托管代码。

无后缀URL的问题

传统上,该系统对asp.net服务器页面来说一切正常,因为它们对应真实的以.aspx为后缀文件真实的存在与磁盘上。但是,对于新的路由系统来说就不是这样了,对于routing来说URL不需要与磁盘上的真实文件对应甚至不需要有扩展名。

这个新的URL路由系统是作为一个.NET HTTP模块创建的。该HTTP模块是被假设为处理所有请求来创建的,该模块是判断和决定对一个请求的控制是否可以转入到你的asp.net mvc项目的某个控制器并由该控制器来接待。但是这是.NET托管代码,所以只有在请求能够激活asp.net的条件下才能够往下进行(比如IIS将请求映射给了aspnet_isapi.dll)。所以除非该请求URL具有合适的扩展名,否则aspnet_isapi.dll根本不会被激活,这意味着IIS将会把该请求作为静态请求尝试返回相应于URL的静态文件的内容,因为磁盘上并没有这个静态文件存在,所以我们将得到一个404 Not Found错误。如何才能做到可以使用无扩展名的URL呢!我们大部分希望将asp.net mvc项目部署到IIS6上的人开始都会遇到这个问题。接下来的文字中我们会给出四个解决方案以供选择。

这篇文章主要从基础和概念上介绍了asp.net mvc项目部署,以及IIS版本变化的情况。

【编辑推荐】

  1. ASP.NET中的session存储模式运用
  2. ASP.NET中的文件上传下载方法集合
  3. ASP.NET中的cookie读写方法介绍
  4. ASP.NET中的javascript操作
  5. ASP.NET2.0中的单点登录简介及实现
责任编辑:book05 来源: cnblogs
相关推荐

2009-07-20 10:53:59

ASP.NET MVC

2009-07-20 15:44:32

ASP.NET MVC

2009-04-01 12:00:43

ASP.NETMVC

2009-07-24 10:41:00

asp.net mvc

2009-07-22 13:16:04

MvcAjaxPaneASP.NET MVC

2009-07-23 18:14:17

MVC生命周期

2009-07-23 10:08:24

asp.net mvc

2015-06-17 10:16:30

ASP.NET

2011-04-14 09:19:22

ASP.NET MVC

2009-07-20 12:59:53

ASP.NET MVCASP.NET框架的功

2009-07-24 13:20:44

MVC框架ASP.NET

2009-07-31 12:43:59

ASP.NET MVC

2009-03-13 10:58:48

ASP.NetMVC框架编程

2009-08-24 09:18:34

ASP.NET MVC

2009-07-20 17:16:46

IIS中使用ASP.N

2009-07-28 16:16:46

IIS5与IIS6.0ASP.NET

2009-07-24 13:41:03

IIS ASP.NET

2009-07-29 02:40:00

asp.net mvc

2009-07-22 10:09:59

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC
点赞
收藏

51CTO技术栈公众号