随着你慢慢的建立WSS跟ASP.NET如何集成到一起的理解, 你就会明白WSS的高层次设计的目标了, 那就是为ASP.NET框架增加实用价值. WSS在ASP.NET之上, 为经常地, 持续地创建, 更新,删除站点这样的环境, 增加了重要的实用价值. WSS还在ASP.NET上, 增加了站点元素创建的一个维度, 允许站点管理员在站点的上下文中, 很快地创建页面, 列表, 还有文档库.
WSS在IIS站点的层次上与ASP.NET进行集成. 每个你想要用它来寄存WSS站点的IIS站点都必须经过一次转换过程, 在这次转换过程中, IIS站点将会被设置为一个用WSS术语说叫做Web Application的东西. 这个转换过程涉及到在IIS metabase中添加入口, 还要添加一个WSS相关的web.config文件到IIS站点的根目录下. 一旦转换过程完成, WSS就扩展了IIS和ASP.NET的路由架构, 扩展的方式是使用WSS运行时来对请求进行合适的路由操作.
我们接下来要讨论WSS应用程序是如何被配置的. 然而, 在你深入这些细节之前, 我们希望你能够做一个重要的观察. 特别地, 从可管理能力和可衡量能力的角度, 我们希望你考虑一下Web Applicaiton是如何作为一个整体嵌入到WSS架构中的.
WSS Web Application的创建是一项重要的需要场级管理员权限的管理任务. 创建一个web application需要在每一个web前端服务器上进行一系列重要的对文件系统和IIS metabase的更改. 在web场环境下, 这些修改会由WSS运行时来自动地镜像到场中其他的web前端服务器上. 创建Web application的步骤仅在初始安装和配置WSS的时候才需要.
一旦一个Web application创建完毕, 那么在就没必要在创建, 更新, 删除站点和站点集的时候再去触碰前端服务器上的文件系统和IIS的metabase了. WSS架构使得仅仅通过在Configuration database(配置数据库)和Content database(内容数据库)中添加一些数据就可以简单地创建新的站点和站点集成为可能. 就是WSS架构的这个方面让WSS在易管理性和易创建性上远远地超出了ASP.NET. 这里添加的易管理性的优势在Web场环境下更是特别明显.
Web Applications
===============
创建Web Application有两条主要的途径, 一个是通过WSS Central Administration(WSS管理中心), 另一个是通过运行STSADM.EXE命令行工具. 首先, 你通过转换一个已经存在的IIS站点来创建一个web application. 你还可以从头创建一个新的web application, 让WSS来为你在后台创建新的IIS站点. 任何一种情况下, WSS都会在IIS站点下添加一个IIS应用程序映射, 还要添加一些虚拟目录. WSS还会拷贝global.asax文件和web.config文件到IIS站点的根目录下.
WSS必须为每一个web application添加IIS应用程序映射, 目的是为了让所有的, 任何一个到来的请求都会初始经过ASP.NET的路由. 记住, 默认的ASP.NET的配置仅仅注册了针对大家都熟悉的ASP.NET的文件后缀名(.aspx, ascx, .ashx, 和.asmx)的应用程序映射. 所以, WSS配置使用一个*号通配符来配置宿主IIS站点, 来让所有的请求都经过aspnet_isapi.dll的处理, 这样就把非ASP的文件后缀诸如.doc, .docx, 和.pdf也都让ASP.NET来处理了.
因为所有的指向web application的请求都被路由经过aspnet_isapi.dll, 所以请求就会完全地用ASP.NET上下文来初始化. 进一步, 请求的处理行为可以被WSS定义的HttpApplication对象来控制, 并且配置元素也添加到了web.config文件中. WSS团队使用标准的ASP.NET技术, 通过使用几个自定义的组件, 如下图, 扩展了HTTP Request Pipeline.
首先, 你能看到WSS配置每一个web application, 通过使用SPHttpApplication类, 设置了自定义的HttpApplication对象. 注意这个类是在WSS系统的程序集Microsoft.SharePoint.dll中部署的. WSS通过在Web Application的根目录下创建自定义的global.asax文件, 来集成这个自定义的应用程序类, web application类继承自SPHttpApplication.
<%@ Application Inherits="Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication" %>
除了包括自定义的HttpApplication对象, WSS架构还试用了一个自定义的HttpHandler和一个自定义的HttpModule. 这两个WSS相关的组件通过在web.config文件中添加标准的入口而被集成到HTTP Request Pipeline 当中. 检查下面的xml片段吧, 它是从WSS3.0 Web Application使用的标准web.config中截取的.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <httpHandlers> <remove verb="GET,HEAD,POST" path="*" /> <add verb="GET,HEAD,POST" path="*" type="Microsoft.SharePoint.ApplicationRuntime.SPHttpHandler, ..." /> </httpHandlers> <httpModules> <clear /> <add name="SPRequest" type="Microsoft.SharePoint.ApplicationRuntime.SPRequestModule, ..." /> <!-- other standard ASP.NET httpModules added back in --> </httpModules> </system.web> </configuration>
WSS团队成员创建了他们自己的HttpModule, 叫做SPRequestModule, 用来初始化各种WSS运行时环境.你可以看到标准WSS的web.config文件中配置的SPRequestModule, 所以, 它是第一个在ASP.NET的HTTP Request Pipeline中的响应应用程序层事件的HttpModule了. 如果你检查WSS web application的web.config文件, 你会看到WSS在后面还添加了许多ASP.NET框架中的标准HttpModule, 用来处理如输出缓存和认证方式的module.
标准的WSS web.config 文件还注册了一个叫做SPHttpHandler的HttpHandler, 并且给它配了一个"*"作为路径. 这允许的WSS使用SPHttpHandler作为所有到来的请求的唯一终点.
Web application的标准web.config文件
===============
前面的部分里, 你看到了包括标准ASP.NET配置元素的用于web application的web.config文件. 然而, WSS在扩展标准ASP.NET的web.config文件上还做了很多, 它还添加了自定义的SharePoint的section. 检查下面的XML片段, 它展示出了web.config文件的SharePoint部分, 还有在configSection中被ASP.NET
需求的用于扩展配置信息的元素.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="SharePoint"> <section name="SafeControls" type="..." /> <section name="RuntimeFilter" type="..." /> <section name="WebPartLimits" type="..." /> <section name="WebPartCache" type="..." /> <section name="WebPartWorkItem" type="..." /> <section name="WebPartControls" type="..." /> <section name="SafeMode" type="..." /> <section name="MergedActions" type="..." /> <section name="PeoplePickerWildcards" type="..." /> </sectionGroup> </configSections> <SharePoint> <SafeMode /> <WebPartLimits /> <WebPartCache /> <WebPartControls /> <SafeControls /> <PeoplePickerWildcards /> <MergedActions /> <BlobCache /> <RuntimeFilter /> </SharePoint> </configuration>
在SharePoint部分中折叠着的配置元素被WSS运行时的多种组件读取. 对每一个折叠在SharePoint部分中的元素, 在configSections中都有一个元素定义了用哪一种配置类在运行时读取这些信息. 这使得在处理一个请求的时候, 不同的WSS运行时组件对于这个WSS特定的配置信息的读取成为可能.
SPVirtualPathProvider
==================
WSS强于ASP.NET的一个方面在于它能够在站点中创建和定制化页面, 而不需要对Web前端服务器上的本地文件系统做任何改变. WSS的这个创建和修改页面的能力是通过两方面实现的: 1. 在内容数据库中存储定制化的版本的aspx文件和master文件; 2. 在他们被进来的请求索要的时候拿到这些文件.
考虑一个简单的WSS中的页面定制化是如何工作的吧. 想象你需要在Microsoft Office SharePoint Designer中修改某个站点的首页(default.aspx)的HTML布局. 当你使用SharePoint Designer修改并保存页面的时候, WSS将整个的定制化了的页面的内容写入到内容数据库中. 在那之后, 当同样的页面被请求时, WSS必须从内容数据库中得到这个被定制化过的页面的定义, 然后交给ASP.NET运行时去解析. 我们现在解释一下始这个过程成为可能的架构细节.
ASP.NET 2.0引入了一个可插入的组件, 叫做virtual path provider. 在virtual path provider背后的想法是让它把页面存储在什么地方从ASP.NET运行时中抽象出来. 创建一个自定义的virtual path provider, 研发人员就可以书写一个自定义的组件来从远程的地址(比如说Microsoft SQL Server数据库)获得ASP.NET的文件类型(比如aspx和master文件). 一旦一个virtual path provider 得到了一个aspx页面的内容, 他就把内容传递给ASP.NET运行时去解析.
WSS团队创建了一个叫做SPVirtualPathProvider的virtual path provider, 并把它集成到每一个web application当中. SPVirtualPathProvider 类通过SPRequestModule集成到ASP.NET的请求处理基础架构中. 更具体地说, SPRequestModule组件中包含代码用来将SPVirtualPathProvider注册到ASP.NET框架中, 因为这是SPRequestModule在初始化Web application时候的工作. 下图展示了SPVirtualPathProvider的角色.
正如你所看到的, SPVirtualPathProvider能够从内容数据库中取到一个ASP.NET的页面文件, 然后传递它给ASP.NET的页面分析器. SPVirtualPathProvider与另一个叫做SPPageParserFilter的类一起工作, 为ASP.NET页面分析器提供处理指令. 比方说, SPPageParserFilter 组件能够控制ASP.NET页面分析器是否将ASP.NET页面编译成程序集DLL, 要么就是用ASP.NET 2.0引入的非编译模式. 以后, 你将会看到如何在web.config中添加入口来告诉SPPageParserFilter去如何处理页面.
SPVirtualPathProvider组件在整个WSS架构中扮演着的一个关键的角色. 正如你看到的, 它为支持页面定制化提供支持. 它还支持一个重要的叫做page ghosting的优化, 这个page ghosting是允许WSS场向外扩展出成千上万个页面的关键因素. 让我提供一个快速的例子, 来说明page ghosting是如何工作的吧.
想象你刚刚用空白站点模板创建了100个新的WSS站点. 如果这些站点中没有一个需要自定义版本的首页(default.aspx), 那么你拷贝这些页面的精准定义到内容数据库中100次还是合理的么? 这个问题的答案显然是No. 幸运地, WSS中的页面如default.aspx是基于存在于web前端服务器的文件系统中的页面模板的. 页面模板被用来在站点的上下文中创建页面的实例, 比如说通过某个特定URL访问的页面, 就像http://litwareinc.com/default.aspx.
当一个页面实例被从页面模板中创建出来的时候, WSS不需要在内容数据库中存储这个页面的一个拷贝, 因为WSS可以从WEB前端服务器上的文件系统中加载起页面模板, 然后使用这个模板来处理任何指向未被自定义的页面实例的请求. 所以, 你可以说page ghosting描述了一种处理指向未被定制化的页面的请求的行动, 该行动通过在前端服务器上把页面模板加载到内存中来完成.
Page ghosting是有价值的, 因为它减少了从SQL Server计算机的内容数据库中拿到文件定义的内容, 再传递给Web前端服务器的需求. page ghosting还使得使用一个编译为DLL的并加载到IIS工作者进程的内存中的页面模板来处理上千个不同站点的首页的处理过程成为可能, 并且每一个Web application来说只用处理一次. 这两种优化在运行成千上万个站点的高负载环境下, 对于提高WSS的可扩展性都是重要的关键因素.
当你使用SharePoint Designer修改一个页面, 然后保存定制化版本的页面到内容数据库中的时候, 你就消除了使用page ghosting的可能性. 作为替代, 提供给你的SPVirtualPathProvider 必须从内容数据库中取回自定义版本的页面文件, 就如同上图展示的一样. 就冲着这个原因, 定制化过的页面有时候也叫做unghosted pages.
现在既然你已经理解了WSS是如何处理请求ghosted和非ghosted的page的了, 那么你应该观察一下SPVirtualPathProvider扮演的角色了. 是SPVirtualPathProvider决定请求的页面是否是被定制化过的. SPVirtualPathProvider做出决定, 是否按照处理ghosted page的方式来处理请求. 更进一步地, 所有的page ghosting 和unghosting都对ASP.NET运行时隐藏了, 表现为WSS的附加价值的一个维度.
学友文章后记: 这是本系列中最最重要的一片文章. 对于理解SharePoint的架构至关重要, 请要了解SharePoint的读者仔细阅读. MSDN上有部分文字(英文的)的节选, 作为介绍SharePoint基础架构的文章.