ASP.NET框架代表着在IIS和ISAPI编程模型之上的一个重要的生产力层. 如果你熟悉ASP.NET开发的话, 你就会知道它为你的应用程序逻辑编写托管代码提供了便利, 比如说C#, VB.NET, 并且允许你在由Microsoft Visual Studio提供的面向生产力的可视化编辑器中工作. ASP.NET框架还提供了许多其他有价值的抽象, 来帮助开发人员进行状态管理, 数据绑定, 导航 以及数据缓存.

ASP.NET框架是由一个叫做aspnet_isapi.dll的ISAPI extension实现的. ASP.NET的基础配置涉及: 在IIS站点或虚拟目录的层次, 为ASP.NET的文件后缀注册映射的应用程序, ASP.NET的文件后缀包括.aspx, .ascx, 和.asmx. 当IIS看到一个指向这些文件类型的请求的时候, 他会把这个请求送给aspnet_isapi.dll, 让它来处理, 这个dll会高效地将控制转移给ASP.NET框架. 所以说, ASP.NET框架处理一个请求的方式很大程度上取决于目标文件的文件类型(扩展名).

ASP.NET框架像一个独立的ASP.NET应用程序一样地执行指向IIS站点和虚拟目录的请求. 在每一个ASP.NET应用程序的身后, 都有一个包括一堆文件的根目录. 这种架构保证了ASP.NET应用程序的部署是一种非常简单的x-copy风格. 你可以简单地在Web服务器上创建一个新的虚拟目录, 然后拷贝你的ASP.NET应用程序的文件到根目录下. 当然, 有一点小麻烦的是在Web场环境中创建虚拟目录, 然后将同样的文件部署到场中的所有前端服务器上.

每个ASP.NET应用程序都可以在它的根目录下被独立地配置web.config文件. web.config文件是一个基于xml的文件, 包含许多元素, 用于控制ASP.NET框架中的各种各样的feature的行为, 比如说编译啦, 页面渲染啦, 状态控制了什么的. 一个简单的web.config文件看起来像下面这样:

<?xml version="1.0" encoding="utf-8" ?>
<configuration><system.web><customErrors mode="On" /><httpRuntime maxRequestLength="51200" /><authentication mode="Windows" /><identity impersonate="true" /><authorization><allow users="*" /></authorization></system.web></configuration>

注意到ASP.NET框架在运行每一个ASP.NET应用程序的时候, 都有一定程度的隔离性. 即使是在你已经配置了多个ASP.NET应用程序运行在同一个IIS Application Pool中的时候, 也有隔离性. ASP.NET框架提供了运行在同一个IIS工作者进程中的对多个ASP.NET应用程序之间的隔离, 隔离方式是把它们分别加载到分开的.NET Framework AppDomain中.[学友注: 关于AppDomain, 可以参考文章走近.NET AppDomain]

ASP.NET页面

===========

页面(page)是ASP.NET框架中最有价值的抽象之一. 开发者构建ASP.NET应用程序, 最典型的方式是在Visual Studio的可视化设计界面上拖拽服务器控件, 和通过标准的属性单来修改页面和控件的属性. ASP.NET框架和Visual Studio还使得向页面中添加处理逻辑相对更加简单了, 达到这个目的的方式是在页面级上的响应事件中和在控件级的事件中通过编写托管代码.

在物理层面, ASP.NET应用程序中的一个页面是一个以.aspx后缀结尾的, 存储在Web服务器上的文件, 在它被客户端请求时, 它会被编译为一个dll文件. 考虑下面的aspx页面定义, 它包含一个服务器端控件和一个简单的事件处理程序.

<%@ Page Language="C#" %><script runat="server">protected override void OnLoad(EventArgs e) {lblDisplay.Text = "Hello, ASP.NET";}
</script><html>
<body><form id="frmMain" runat="server"><asp:Label runat="server" ID="lblDisplay" /></form>
</body>

在后台, ASP.NET框架做了不少工作来把.aspx文件编译成为一个dll文件. 首先, 它必须先将aspx文件解析并生成一个C#(或VB.NET)的源文件, 源文件中包含一个继承自Page类的公有类, Page类是定义在System.Web.UI命名空间下的, 存在于system.web.dll这个程序集中. 当ASP.NET页面解析器生成这个继承自Page的类时, 它建立一个控件的树形结构, 包括页面中定义的所有的服务器端控件. 页面解析器同时添加需要的代码来勾住页面中定义的任何的事件处理程序.

一旦ASP.NET页面解析器建造好了.aspx的源文件, 它就开始编译这个源文件成为一个DLL. 这个编译自动发生在这个.aspx页面第一次被请求的时候. 一旦ASP.NET运行时编译好了aspx文件的DLL, DLL的一份拷贝会被用来为所有后来的指向同样aspx文件的请求服务. 然而, ASP.NET运行时会监视DLL的时间戳, 如果它发现与DLL相关联的aspx文件被更新了, 它就会重新编译来重建那个DLL.

ASP.NET框架如此流行的原因之一, 就是因为它方便的服务器端控件. 使用与ASP.NET框架一同release的开箱即用(out-of-box)的控件创建页面非常容易.控件有很多, 比如validation控件, calendar控件, 还有支持数据绑定的控件, 比如GridView控件还有Repeater控件. 还有呢, 开发者创作自定义的控件并把它用在页面里也是相对容易的.

母版页

================

ASP.NET 2.0引入了母版页(master page), 它提供了一种非常高效的创建页模板的方式. 特别地, 一个母版页定义了可以在许多不同页面间使用的通用元素(比如说顶部横幅top banner), 还有站点导航控件. 在母版页中定义的布局可以被很多跟这个母版页链接到一起的页面使用. 在ASP.NET技术中, 与一个母版页链接到一起的页面叫做content page(内容页). 母版页与内容页的基本关系在下面可以看到图示:

举例, 假设你希望创建一个母版页, 用来定义一个HTML布局, 这个布局包括一个横幅在页的顶部. 你应该创建一个后缀名为.master的文件作为开始, 就叫default.master吧. 下一步你应该在页面的顶部添加一个@Master指令. 然后, 在下面你定义页面的HTML布局, 添加并命名placeholders, 就如下面的例子一样:

<%@ Master %>
<html>
<body><form id="frmMain" runat="server"><table width="100%"><tr><td> <!-- Display Litware Banner --><h1>Litware Inc.</h1><hr /></td></tr><tr><td> <!-- Display Main Body of Page --><asp:contentplaceholder id="PlaceHolderMain" runat="server" /></td></tr></table></form>
</body>
</html>

当你想创建一个内容页时, 你应该创建一个.aspx文件, 然后添加一个@Page指令, 其中包括MasterPageFile属性. 一旦你决定你想要取代母版页中的哪一个命名的placeholder, 你就为这个取代操作定义一个Content元素. 接下来是一个简单的内容页链接起一个母版页的例子, 代码中取代了母版页中的名为PlaceHolderMain的placeholder.

<%@ Page Language="C#" MasterPageFile="~/default.master" %>
<script runat="server">protected override void OnLoad(EventArgs e) {lblDisplay.Text = "Hello World";}
</script>
<asp:Content ID="main" Runat="Server" ContentPlaceHolderID="PlaceHolderMain" ><asp:Label ID="lblDisplay" runat="server" />
</asp:Content>

注意当你创建了一个内容页并指向了一个母版页了的时候, 所有你想添加的的HTML必须写在指向某个名字的placeholder的Content元素中. 如果你在Content元素之外写了HTML代码或者是服务器端控件, 那么这个页面就不会被编译. 但是, 如同你在之前的例子中看到的, 你可以在Content元素之外添加一个脚本块, 并在脚本块中添加任何你想添加的代码.

当一个母版页定义了一个命名了的placeholder, 你并不需要一定总是在你的内容页中取代它. 因为, 母版页创建带有的默认内容的placeholder.  任何指向那个母版页的内容页, 只要不包括那个命名了的placeholder, 就会得到母版页中定义的默认内容.  另一个连接到同样母版页的内容页, 并且其中包含了那个命名的placeholder, 会用自己的自定义内容取代默认内容.

最后, 注意不管是谁, 只要他创建了母版页, 那他就得决定placeholder的名字, 还要决定哪个包含什么样的默认内容. 这对于设计WSS站点的页面时很重要, 因为你创建的内容页将会指向由WSS团队创建的母版页. 在这种情况下, 你必须学会WSS团队定义了什么placeholder, 还有哪些种类的内容是可以取代的.

HTTP请求的pipeline

================

在面向高产的页面和服务器端控件架构之下, ASP.NET框架为想要在更深一个层次的开发者暴露了HTTP请求Pipeline. 他给开发者提供了可以跟ISAPI编程模型在某种程度相比的控制. 然而, 当你为HTTP请求pipeline创建组件的时候, 你却可以使用如C#或VB.NET一样的托管代码. 你还可以使用由ASP.NET提供的API, 这可比直接使用ISAPI编程模型容易多了.

下图展现了HTTP request pipeline和它的三个可以替代的组件类型: HttpHandler, HttpApplication, 和HttpModule. 当请求进来的时候, 他们被排入队列, 并被赋给一个工作者线程, 然后通过与这三个组件类型的交互来处理这个请求.

任何请求的最后的终点, 你可以在图中看到, 是HttpHandler类, 它继承了IHttpHandler接口. 作为一个开发者, 你可以创建一个自定义的HttpHandler组件, 然后通过在web.config中添加设置元素来把你的HttpHandler插入到HTTP request pipeline中.

Http Request Pipeline在HttpHandler之前放置了一个HttpApplication组件. 在一个应用程序范围的基础上, 进来的请求在到达HttpHandler之前, 总是通过HttpApplication来路由的. 因此, 给了HttpApplication一个不管最后被路由到哪个HttpHandler, 它总能预处理任何请求的能力. 这个预处理阶段是通过一系列的在HttpApplication中定义的事件来控制的, 比如说BeginRequest, AuthenticateRequest, 和AuthorizeRequest.

在你不想使用自定义的HttpApplication组件的情形下, ASP.NET使用一个标准的HttpApplication对象来初始化Http Request Pipeline. 然而, 你可以通过创建一个叫做global.asax的文件, 把它放到ASP.NET应用程序的根目录下来取代这个标准的HttpApplication组件. 举个例子, 你可以创建一个看起来像下这样的global.asax:

<%@ Application Language="C#" %><script runat="server">protected void Application_AuthenticateRequest(object sender, EventArgs e) {// your code goes here for request authentication}protected void Application_AuthorizeRequest(object sender, EventArgs e) {// your code goes here for request authorization}
</script>

HTTP Request Pipeline中可以替换的第三个组件类型是HttpModule. HttpModule跟HttpApplication组件相似, 它被设计用来处理HttpApplication类定义的事件, 并且这些事件的处理发生在请求被传送给任何一个HttpHandler类型之前. 比方说, 你可以创建一个自定义的HttpModule组件来处理请求层次的时间, 比如说BeginRequest, AuthenticateRequest, 和AuthorizeRequest. 跟HttpHandler一样, HttpModule类是通过一个接口来定义的. 你可以创建一个实现IHttpModule接口的类, 然后通过在web.config文件中添加配置元素来把你的HttpModule插入到Http Request Pipeline中.

鉴于HttpApplication组件可以被定义为像带着.asax后缀的文本文件一样的简单, 自定义的HttpModule组件总是会被程序集DLL中的类一样被编译. 要添加一个自定义的HttpModule组件到Http Request Pipeline中, 你就得在web.config文件中添加入口.

尽管HttpApplication和HttpModule组件在所做的事情上非常相似, HttpModule包含一些值得注意的不同. 首先, 不像HttpApplication组件那样必须在一个应用程序中只添加一个HttpApplication组件, 对于HttpModule组件, 你的添加没有数量上的限制. ASP.NET的web.config文件可以添加多个不同的HttpModule组件. 第二, HttpModule组件可以被设置在机器的水平上. 事实上ASP.NET框架附带了好几个不同的HttpModule组件, 他们被自动的配置在机器机上运作, 来为ASP.NET提供诸如Windows authentication, Forms Authentication和输出缓存等功能.

对于HTTP Request Pipeline 我们要讨论的最后一个组件是HttpContext. 随着ASP.NEt初始化一个请求并发送给HTTP Request Pipeline, 它还用HttpContext类创建一个对象, 并使用重要的上下文相关的信息来初始化这个对象.

从时间的角度来说, 在ASP.NET在HTTP Request Pipeline中的任何自定义的代码有机会执行之前, HttpContext对象就已经被创建出来了, 认识到这一点很重要. 这意味着你永远可以使用HttpContext对象和它的子对象进行编程, 比如说Request, User, 和Response. 无论何时你开发一个用来在Http Request Pipeline中运行的组件, 你都可以写像下面这样的代码:

HttpContext currentContext = HttpContext.Current;
string incomingUrl = currentContext.Request.Url;
string currentUser = currentContext.User.Identity.Name;
currentContext.Response.Write("Hello world");

<Inside Microsoft Windows SharePoint Services 3.0>

SharePoint基础之六- SharePoint基础架构中涉及的ASP.NET架构相关推荐

  1. 三层架构中ajax,基于mvc三层架构和ajax技术实现最简单的文件上传

    前台页面提交文件 文件操作 上传文件 //上传文件 function upFile() { var file = document.getElementById("UpFile") ...

  2. 如何在微服务架构中实现安全性?

    点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 作者 | Chris Richardson 网络安全已成为每个企业都面临的关键问题.几乎每天都有 ...

  3. 网站如何经过身份验证_如何在微服务架构中实现安全性?

    首先为自己打个广告,我目前在某互联网公司做架构师,已经有5年经验,每天都会写架构师系列的文章,感兴趣的朋友可以关注我和我一起探讨,同时需要架构师资料的可以私信我免费送 作者 | Chris Richa ...

  4. 【软考系统架构设计师】2017下系统架构师案例分析历年真题

    [软考系统架构设计师]2017下系统架构师案例分析历年真题 2017下系统架构师案例分析历年真题 [软考系统架构设计师]2017下系统架构师案例分析历年真题 2017下系统架构师案例分析试题一(系统架 ...

  5. 微服务架构的优缺点_微服务架构DNS服务注册与发现实现原理

    微服务架构已经成为中小型企业必备的项目支撑能力,尤其互联网BATJ企业在04年已经非常成熟,在大规模的核心业务实战中总结了很多大规模服务调度与大数据集的处理方案.微服务架构中涉及到很多模块,本文以微服 ...

  6. 计算机网络建设中涉及到哪些硬件,网络基础知识入门

    网络基础知识入门 导语:随着计算机的广泛应用和网络的流行,我们应该要知道一些网络基础知识,下面是小编收集整理的网络基础入门知识,欢迎参考! 计算机网络是什么 这是首先必须解决的一个问题,绝对是核心概念 ...

  7. php杂谈【基础篇】之_7.PHP涉及的所有英文单词

    php杂谈[基础篇]之_7.PHP涉及的所有英文单词 拦路虎 PHP再火,也会让一部同学心生畏惧,因为看到编辑器中那一串串英文单词,担心自己英文不好,从而对能学会PHP的决心产生动摇.其实大可不必,英 ...

  8. 9.4 基础和应用的平衡中找到大学的节奏——《逆袭大学》连载

    返回到[全文目录] 目录 9.4 基础和应用的平衡中找到大学的节奏 基础与应用兼顾的三种对策 大学四年的节奏--基础和应用的均衡 以实践入手,打开基础学习的大门 课外的自主性学习的路线 9.4 基础和 ...

  9. java基础巩固-宇宙第一AiYWM:为了维持生计,架构知识+分布式微服务+高并发高可用高性能知识序幕就此拉开(一:总览篇)~整起

    PART1:项目情景发展历程:很久很久以后,敏小言和老胡开的小超市,突然发生了一些变故: 超市中除了柜台格子业务之外,还有用户.视频.签到.评论.数据处理等业务[之前,咱们项目中的用户.视频.签到.评 ...

最新文章

  1. 敏捷的四个仪式你了解吗?
  2. 4.4 开发模式下的测试:简化我们对链码的测试过程
  3. 信用评分python_信用评分卡(python)
  4. Java API 设计清单
  5. Dubbo(三) 消费者、提供者工程搭建并实现远程调用
  6. 扫地机器人开机充电还是关机充电器_新手机是开机充电好,还是关机充电好,老司机告诉你...
  7. android安装apk提示版本号不同,android 安装apk 遇到的问题
  8. java的lr词法编译器,自制编译器 青木峰郎 笔记 Ch3 词法分析的概要
  9. 记录学习antd design pro dva的过程,主要记错, 多图预警,如有理解偏差,忘指出,多谢!...
  10. python做自动化控制postman_Python自动化学习笔记(1)认识接口测试以及postman、Charles工具简单应用...
  11. atomic_fetch_add
  12. linux-vi命令
  13. 2022年第十三届蓝桥杯省赛--难度评价
  14. 测试网卡芯片型号的软件,查看电脑无线网卡型号_查看无线网卡芯片型号
  15. 计算机描绘的基因结构图,推荐一款好用的基因结构图在线绘制工具!
  16. Apache新晋董事姜宁:从Apache Member到Apache董事,他花了11年
  17. 一个女孩写给一个男孩子的信
  18. 基于C++实现的图像检索系统
  19. Android 全屏悬浮窗适配(悬浮窗沉浸式)
  20. 【无标题】8421码,5421码,2421码,余3码之间的区别。

热门文章

  1. 当不使用会话状态时禁用它
  2. K-最近邻法(KNN)简介
  3. 【Qt】QCloseEvent的使用小结
  4. java简介 ppt 精_《JAVA》5选择结构精篇课件.ppt
  5. php $this self,php中self与$this的区别
  6. Linux查看WAS的jvm信息,linux 下使用命令查看jvm信息
  7. linux更改文件夹权限_Linux 一些重点知识,整理的很全面,有必要收藏
  8. matlab ros 手势识别,使用MATLAB读取分析ros记录的.bag文件
  9. 操作系统学习2:操作系统的发展和概览
  10. Java多线程复习:3(在操作系统中查看和杀死进程线程)