asp

位置:IT落伍者 >> asp >> 浏览文章

以 Cassini 来宿主 ASP. NET 客户端


发布日期:2022年08月24日
 
以 Cassini 来宿主 ASP. NET 客户端

早在 月和 月发行的 MSDN Magazine 中我讲述了如何构建 ASP 应用程序的客户端环境也就是运行 ASP 网页的无服务器环境(参见 前沿技术A Clientside Environment for ASP Pages 和 前沿技术A Clientside Environment for ASP Pages art 这些专栏的灵感源自下面的情况

假设您的一个客户需要利用一张 CD 来在线发布某些内容例如百科全书黄页或文档集客户需要在 CD 内包含一个查看器应用程序和一种灵活的软件体系结构来传送内容另外除了有处理器最低性能和使用最新版本的 Windows 要求外客户希望 CD 没有什么特殊的系统要求从而方便用户使用这意味着最终的应用程序不应依赖于国内版本 Windows 中包括的 Microsoft Internet 信息服务 (IIS) 或个人 Web 服务器它应在纯粹的无服务器的环境下离线运行

在很多情况下客户有现成的在线内容 Web 站点在其它情况下作为项目的一部分她计划为在线内容创建 Web 站点在这种情况下利用 ASP 或 ADONET 来做这项工作是很明智的选择因为它们非常灵活并且功能强大可使您快速有效地构建查看器应用程序但是自定义应用中果真能够宿主 ASP 或 ADONET 吗?

大约三年前当我第一次探讨这个问题时ADONET 还没有发布只是谣传有一种暂定被称为 ASP+ 的东西这种东西很炫并且不久即将发行那时没有可用来在 IIS 之外以离线方式呈现 ASP 页的工具更糟糕的是设计 ASP 并不能轻松地完成这样的宿主操作因此我提出一种由两部分构成的 ASP 模拟器一种专用的浏览器以及一个 ASP 服务器模块构建的浏览器用来截取任何形式的提交与 URL 请求并且将它们重定向到我自己的 ASP 服务器模块反过来ASP 服务器将从磁盘加载资源解析其内容从而动态生成 HTML 代码该浏览器还负责利用与各种响应请求和服务器 ASP 对象几乎完全相同的编程接口来实例化与初始化伪对象 概括了总体体系结构

虽然不是理想的解决方案但它还是满足了客户的期待并整合成一种较大型的产品今天仍然能够使很多专业人士使用在线和离线的内容根据从这些专栏发布起我获得的反馈信息可以判断出很多开发人员都面临过类似的挑战

几个月后Microsoft 发布了第一个 beta 版的 ADONET我思考着利用该新产品重新访问我的解决方案ADONET 的设计是模块化的所以很适合于宿主在外部应用中包括 IIS 自身但是能够在自定义应用程序中宿主 ADONET 并不等于构建了一种由 CD 提供的离线 Web 浏览器的现成解决方案在自定义应用程序中宿主 ADONET 运行库引擎仅是离线提供动态内容的第一步如果看看图 中所示的体系结构您就会发现它基于两个不同的组件 — 一个还接受用户输入的请求处理器和一个生成实际 HTML 代码的 ASP 源处理器宿主 ADONET 引擎只是取代了图 中的 ASP 服务器模块实际上您需要更多的东西 — 在理想情况下需要的是一个浏览器和一个嵌入的 Web 服务器

ADONET Cassini 示例 Web 服务器(参/Projects/Cassini/Download)是一种可以集成部署解决方案的压缩本地 Web 服务器Cassini 采用 ADONET 宿主 API(SystemWebHosting 命名空间)来创建简单的托管 Web 服务器套接字连接是通过 SystemNet API 来处理的可从 Microsoft 获得 Cassini 的源代码 显示了基于 Cassini 的离线 Web 应用程序的典型体系结构您可以看到整个方案就像是一种基于 Internet 的典型 Web 应用程序但是更为简单很显然Cassini 既不是 IIS 的完全代替物也不是 Microsoft 版的开放源代码 Web 服务器Cassini 是本地的 Web 服务器用来处理对本地文件夹的本地调用我将回顾一下 Cassini 组件然后为您说明如何在 CD 上部署 Web 站点并以此作为结束

宿主 ADONET 运行库

ADONET 应用程序并不要求将 IIS 作为主机模块事实上ADONET 甚至不要求用 Web 服务器来运行它公开了一个任何调用方都能使用的尽人皆知的接口连接并要求内部的 HTTP 管道处理请求

宿主 ADONET 引擎时两个类起着重要的作用 — ttpRuntime 和 ApplicationHost前者是对象的管道的入口点它更像一条装配链可以将 aspx 资源的原始 HTTP 请求转变为全新的 HTML 文本后者使得客户端应用程序宿主 ADONET 引擎成为可能ApplicationHost 类负责创建主机进程中的 AppDomain该进程将处理新应用程序的所有传入请求

Tim Ewald 和 Keith Brown 在他们的文章HTTP Pipelines: Securely Implement Processing Filtering and Content Redirection with HTTP Pipelines in ADONET(MSDN 杂志 月刊)中全面讲述了 HttpRuntime 类的内部组成只在应用程序主机收到并预处理请求时才使用 HttpRuntime 类应用程序主机将所有请求信息打包到一个请求类中该请求类派生于 HttpWorkerRequest 抽象类或更可能派生于其名为 SimpleWorkerRequest 的标准实现类在准备好使用请求类实例后主机将处理权移交给 HttpRuntime调用其 ProcessRequest 静态方法如下列代码所示

SimpleWorkerRequest req;

req = new SimpleWorkerRequest(aspx null ConsoleOut);

HttpRuntimeProcessRequest(req);

前面的代码片断显示了启动对 ADONET 网页进行处理的核心代码该代码的执行由通过 ApplicationHost 创建的主机类的某个特殊方法来控制稍后我将回到该主题现在绝对可以说SimpleWorkerRequest 的构造函数根据 ASPX 资源的虚拟路径进行处理采用一个可选的查询字符串并采用文本编写器对象作为输出您可以使用流编写器对象(而不是标准输出控制台)将 HTML 代码保存到磁盘

ApplicationHost 类

主机和 ADONET HTTP 运行库之间的交互是由名为 ApplicationHost 的特定 Microsoft NET Framework 类来控制的从 ADONET HTTP 运行库的角度来看主机只是调用方 — 即创建了当前的 AppDomain 并且通过调用 ProcessRequest 方法为特定的请求提供服务的模块ADONET HTTP 运行库和主机之间的接口都由 ApplicationHost 类的操作来完成HTTP 运行库全然没有调用方的特性 — 而完全是一个像 IIS 一样的 Web 服务器一个像 Cassini 一样的的本地 Web 服务器或者甚至就是一个片刻就可以创建的简单应用程序ADONET 可以为调用 HttpRuntimeProcessRequest 并传递正确信息的任何模块提供服务 说明了 ADONET HTTP 运行库和其它部分的关系

将 ADONET 宿主在应用程序中的第一步就是创建新的应用程序主机这可以通过调用 ApplicationHost 类的 CreateApplicationHost 静态方法来完成CreateApplicationHost 在调用方进程中创建新的 AppDomain之所以需要新的 AppDomain 是因为 ADONET 要依靠一些设置这些设置只能在 AppDomain 级进行设置并且某些设置只能在创建 AppDomain 之前进行这些设置的一部分是投影复制缓存位置的应用程序基本路径和目录CreateApplicationHost 需要一个虚拟文件夹才能工作这意味着在第一次访问某个新的虚拟文件夹时就会创建一个新主机并随后创建新的 AppDomain(注意像 Cassini 这样的简单 Web 服务器一次只需要一个虚拟文件夹但这只是一种特殊情况

在创建主机接口对象后典型的主机应用程序就开始监听请求如果主机的工作方式与 Web 服务器的相同它就要通过端口 开始监听传入的消息否则它可以是您指定的任何端口然后将请求打包到请求类中并传递给 ADONET 运行库

HttpRuntimeProcessRequest 方法通过对象的管道路由 Request 对象在通道末端会出现一个新对象 — 就是动态创建类的一个实例该类是 Page 类的继承类该实例表示被请求的 aspx 页要结束该请求HTTP 运行库要调用 Page 类的ProcessRequest 方法该页的 ProcessRequest 方法执行 Page 对象的大量任务每项任务都以事件作为信号通过利用 runat=server 属性集来为该页的每个组成元素创建服务器控件实例对该页进行首次初始化接着ADONET 代码加载该页的视图状态并将它与发送的数据(如文本框和复选框的值)合并最后运行库执行客户请求的任何服务器代码(大部分为回发事件)保存视图状态并将 HTML 写到输出编写器中

CreateApplicationHost 静态方法是 ApplicationHost 类的唯一成员它的 C# 原型如下所示

public static object CreateApplicationHost(

Type hostType

string virtualDir

string physicalDir

);

以上代码片断所示的 virtualDir 参数表示所创建的应用域的虚拟目录而 physicalDir 参数表示此虚拟路径后的文件系统路径 — 被请求的 aspx 文件必须从该磁盘文件夹为该 Web 应用程序进行加载这些信息都与域相关并由 ADONET 工厂对象用来创建 HttpApplication 对象 (globalasax) 和网页对象 (aspx)

CreateApplicationHost 的第一个参数是类型对象它的赋值是应用程序定义的主机类的类型这种方法返回用户提供的类的实例该类用来连接主机程序的默认 AppDomain 和新近创建的 AppDomain(参见图 主机类型对象是类似服务器应用程序的核心代码和目标 AppDomain(CreateApplicationHost 先前创建)中 ADONET HTTP 运行库之间的一种代理

上一篇:ASP错误全集错误

下一篇:AspNetPager分页