韩冰 发表于 2005-1-16 11:18

在没有 IIS 的条件下运行 ASMX

<P>来源:<a href="http://www.microsoft.com/china/" target="_blank" >http://www.microsoft.com/china/</A></P>
<P>当 Microsoft&reg; .NET Framework 第一次发布时,它引入了一个有突破性的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>框架,那就是 ASMX。设计 ASMX 的目的在于尽可能地简化 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>的开发过程,这样即使您不是 XML 专家,也可以创建并运行 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>。ASMX 是通过隐藏大多数基础 XML 和 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>细节来实现这一点的。与强制开发人员直接处理 SOAP 信封和 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>描述语言 (WSDL) 文件不同,ASMX 引入了自动映射层,从而实现了与传统 .NET <a href="http://hackbase.com/hacker" target="_blank" >代码</A>的连接。</P>
<P>ASMX 也和流行的 ASP.NET HTTP 管线紧密集成。因此,它具有传统 ASP.NET Web 应用程序的优点,例如,高级的宿主环境和进程模型、可靠的配置和部署选项,以及灵活的扩展性点。结果,ASMX 通常是大多数 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>开发人员的首选。大多数开发人员错误地认为 ASMX 需要 IIS;毕竟,他们所见过的都是这种情况。但事实上,ASMX 在<a href="http://hackbase.com/network" target="_blank" >技术</A>上与 IIS 并没有任何依赖关系。</P>
<P>在没有 IIS 的条件下宿主 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>的需要是非常实际的。在某些环境下,可能有各种原因导致无法在必须宿主 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>的<a href="http://hackbase.com/skill" target="_blank" >计算机</A>上运行 IIS。幸运的是,在没有 IIS 的条件下,您可以在您的进程中宿主 ASMX。自从 .NET Framework 1.0 发布以来,就可以实现这一点,但是您必须提供您的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器来接收 HTTP 请求。Cassini 是由 ASP.NET 团队开发的一个示例 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器,它可以满足这种需要,并允许您在没有 IIS 的条件下运行 ASP 页。然而,对于大多数开发人员来说,编写他们自己的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器或者使用诸如 Cassini 的示例 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器都是不合理的。</P>
<P>自从 Windows Server™ 2003 和 Windows&reg; <a href="http://hackbase.com/skill/XP" target="_blank" >XP</A> SP2 发布以后,出现了一个新的 HTTP <a href="http://hackbase.com/network/protocol" target="_blank" >协议</A>栈,名为 http.sys。通过 http.sys 和 .NET Framework 2.0 中的一些新托管类(特别是 HttpListener),您就可以轻松地为您的应用程序构建 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器,而无需在<a href="http://hackbase.com/skill" target="_blank" >计算机</A>上安装 IIS。这些进展使得在任何环境中运行 ASMX 成为可能。请注意,.NET Framework 2.0 当前只是测试版,因此还会有所改动。</P>
<P>
ASP.NET HTTP 体系结构</P>
<P>ASP.NET 专门设计为避免依赖于 IIS。基础体系结构是由共同处理传入的 HTTP 消息的 .NET 类构成的一条管线。它被看作管线的原因是每个 HTTP 请求都要经过一系列对象,每个对象执行一些处理。</P>
<P>HttpRuntime 类位于管线的前端,负责启动进程。当调用 HttpRuntime 类的静态 ProcessRequest 方法时,管线开始执行。ProcessRequest 带有一个 HttpWorkerRequest 对象,该对象包含当前请求的所有信息。HttpRuntime 使用 HttpWorkerRequest 中的信息来填充 HttpContext 对象。然后它实例化适当的 HttpApplication 类,这个类会调用注册到应用程序的任何 IHttpModule 实现以用于预处理或后期处理。此时会识别、实例化和调用适当的 IHttpHandler 实现。</P>
<P>每个进入管线的 HTTP 请求都会发生这个过程。所有 ASP.NET 功能(包括 ASMX 的功能)都包含在这些管线类中。例如,当请求到达 System.Web.Services.Protocols.WebServiceHandlerFactory 类时,就开始支持对 ASMX 终结点的处理,该类负责识别、编译(如果需要)和实例化标识的 ASMX 类,以及调用传入的 SOAP 消息的目标 WebMethod。</P>
<DIV ><IMG src="http://www1.hackbase.com/UpLoadFiles/NewsPhoto/SMXfig01.gif" border=0>

<P><B>图 1 HTTP管线和 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器</B></P>
<DIV class=figureRule></DIV></DIV>
<P>管线是完全自治的,与 IIS 相互独立。甚至当与 IIS 一起使用时,也是在与 inetinfo.exe 独立的进程中运行的。这个进程的名称取决于主机 OS(在 Windows <a href="http://hackbase.com/skill/XP" target="_blank" >XP</A> 上为 aspnet<a href="http://www1.hackbase.com/network/network/200501169554.htm#" target="_blank" >_</A>wp.exe,在 Windows Server 2003 上为 w3wp.exe)。除了有自己的进程模型外,管线也有独立的配置方式,与 IIS 元<a href="http://hackbase.com/hacker" target="_blank" >数据库</A>是分开的。管线唯一没有的就是可用来接收传入的 HTTP 请求的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器。您仍需要一些能够侦听传入的 HTTP 消息的组件,如 IIS 5.0 或 http.sys。即使是这样,这些组件也只是负责接收 HTTP 请求并将它们交给 ASP.NET 管线,这以后的任何事情都要由它来处理(请参见<B>图 1</B>)。</P>
<P>一旦该请求使其进入辅助进程,辅助进程就会创建 HttpWorkerRequest 对象(表示传入的请求)并调用 HttpRuntime.ProcessRequest 来启动管线。由于有了这样合理的设计,您就可以直接在自己的应用程序中调用 HttpRuntime。</P>
<P>
宿主 HTTP 管线</P>
<P>宿主 ASP.NET 所需要的类可以在 System.Web 和 System.Web.Hosting 命名空间中找到。开始时需要用到的类主要有 ApplicationHost、HttpRuntime 和一个从 HttpWorkerRequest 派生的类。首先调用 ApplicationHost.CreateApplicationHost。这个方法新创建一个可以处理 ASP.NET 请求的应用程序域 (AppDomain)。由于您要显式创建 AppDomain,因此在调用时必须指定虚拟目录和相应的物理目录。</P>
<P>除了创建新的 AppDomain 以外,CreateApplicationHost 还在这个新的 AppDomain 中实例化了一个对象,您可以通过这个对象进行通讯。当进行该方法调用时,您要指定要让它实例化的类型。由于该对象将跨 AppDomain 边界使用,因此它必须从 MarshalByRefObject 派生。您可能想要使用自己的类,它具有与 AppDomain 交互所需要的方法。例如,至少您想要一个 ProcessRequest 方法,它可以提交新的 ASP.NET 请求以进行处理。</P>
<P>这里有一个类可用来实现该目的: </P><PRE>public class MySimpleHost : MarshalByRefObject
{
    public void ProcessRequest(string file)
    {
       ... // use the ASP.NET HTTP pipeline to process request
    }
}
</PRE>
<P>在本例中,ProcessRequest 接受要处理的页面的文件名。在 ProcessRequest 中,您可以使用 HttpRuntime 来启动管线处理。HttpRuntime 有一个静态方法,名称也叫做 ProcessRequest,它带有一个 HttpWorkerRequest 类型的参数。 </P>
<P>HttpWorkerRequest 是一个抽象类,但幸运的是,.NET 附带了一个简单的、名为 SimpleWorkerRequest 的派生类,它旨在处理简单的 HTTP GET 请求。当您实例化 SimpleWorkerRequest 时,必须指定要处理的页面的名称、一个可选的查询字符串和一个 TextWriter(管线将输出写入其中)。一旦您拥有 HttpWorkerRequest 对象,您就可以通过调用 ProcessRequest 来调用管线,如下所示: </P><PRE>... // MySimpleHost.ProcessRequest
SimpleWorkerRequest swr =
  new SimpleWorkerRequest(page, null, Console.Out);
HttpRuntime.ProcessRequest(swr);
</PRE>
<P>对于 MySimpleHost,您需要在宿主应用程序中调用 ApplicationHost.CreateApplicationHost 来实例化这个对象。然后,可以使用 MySimpleHost.ProcessRequest 将请求发送给 HTTP 管线进行处理,如以下<a href="http://hackbase.com/hacker" target="_blank" >代码</A>片段所示: </P><PRE>... // console host application
MySimpleHost msh = (MySimpleHost)
  ApplicationHost.CreateApplicationHost(typeof(MySimpleHost), "/",
    Directory.GetCurrentDirectory());
foreach (string page in args)
  msh.ProcessRequest(page);
</PRE>
<P>ApplicationHost.CreateApplicationHost 的实现期望在以下两个位置之一找到指定类型的程序集:在全局程序集缓存 (GAC) 中,或者在指定物理目录的 bin 目录中。由于没有文档化的方式可以更改这种重新实现 CreateApplicationHost 的行为缺陷,因此根据您的项目配置和部署方案,可能需要在其中的一个位置安装程序集。</P>
<P><a href="http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx?fig=true#fig2" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>图 2</FONT></EM></A> 包含宿主 ASP.NET 的整个控制台应用程序的<a href="http://hackbase.com/hacker" target="_blank" >代码</A>。该示例可以下载。您在命令行中指定 ASP.NET 文件的名称以及一个可选的查询字符串。然后该程序会通过调用 MySimpleHost.ProcessRequest 将它们传递给管线。</P>
<P>在本专栏的下载中,我提供了几个 ASP.NET 文件以供您试用,其中包括一个名为 math.asmx 的文件。当您运行应用程序时,请在命令行中指定“math.asmx WSDL”,您会看见打印在控制台窗口中的、由 ASMX 生成的 WSDL 定义(等价于通过宿主在 IIS 中的 math.asmx 浏览 http://<I>host</I>/math.asmx?WSDL)。如果您只在命令行中指定“math.asmx”,则它会打印由 ASMX 生成的可读的文档页面。</P>
<P>这明显是个不实际的例子,因为您必须在命令行中指定 ASP.NET 页。在实际应用中,这个信息会通过 HTTP 请求传入。为了支持 HTTP,您需要在应用程序中集成一个 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器。</P>
<P>
别了,IIS </P>
<P>Http.sys 是一个新的低级 HTTP <a href="http://hackbase.com/network/protocol" target="_blank" >协议</A>栈,可在 Windows Server 2003 和 Windows <a href="http://hackbase.com/skill/XP" target="_blank" >XP</A> SP2 中使用。Http.sys 是一个内核模式组件,它为<a href="http://hackbase.com/skill" target="_blank" >计算机</A>中的所有应用程序提供它的 HTTP <a href="http://vip.hackbase.com/" target="_blank" >服务</A>。这意味着 HTTP 支持深深依赖于 OS。甚至 IIS 6.0 也进行了重新架构,以便可以使用 http.sys(请参见<B>图 3</B>)。</P>
<DIV ><IMG src="http://www1.hackbase.com/UpLoadFiles/NewsPhoto/SMXfig03.gif" border=0>

<P><B>图 3 Http.sys 体系结构</B></P>
<DIV class=figureRule></DIV></DIV>
<P>在 6.0 版之前,IIS 依靠 <a href="http://hackbase.com/hacker" target="_blank" >TCP/IP</A> 内核和 Windows Sockets API (Winsock) 接收 HTTP 请求。由于 Winsock 是一个用户模式组件,因此每个接收操作都需要在内核模式和用户模式之间进行切换。现在 Http.sys 可以直接在内核中缓存响应。当处理缓存的响应时,将 HTTP 栈放在内核中可以使得移除代价昂贵的上下文切换成为可能,从而提高效率和整体吞吐量。</P>
<P>当 http.sys 接收到请求时,它可以直接将该请求转发到正确的辅助进程中。另外,如果辅助进程无法接受该请求,http.sys 会存储该请求,直到辅助进程启动并可以接受它为止。这意味着辅助进程失败不会中断<a href="http://vip.hackbase.com/" target="_blank" >服务</A>。当 IIS 6.0 启动时,WWW <a href="http://vip.hackbase.com/" target="_blank" >服务</A>会与 http.sys 进行通讯,并为配置的每个 IIS 应用程序注册路由信息。无论您何时在 IIS 中创建应用程序或移除应用程序时,WWW <a href="http://vip.hackbase.com/" target="_blank" >服务</A>都会与 http.sys 进行通讯以更新它的路由信息。</P>
<P>正如您在<B>图 3</B> 中所看到的,http.sys 为 IIS 6.0 Web 体系结构奠定了基础,但它没有以任何方式与 IIS 产生联系。运行在<a href="http://hackbase.com/skill" target="_blank" >计算机</A>中的任何应用程序都可以利用 http.sys 来接收 HTTP 请求。与 WWW <a href="http://vip.hackbase.com/" target="_blank" >服务</A>相似,您可以用 http.sys 注册应用程序,并开始侦听传入的 HTTP 请求。.NET Framework 2.0 引入了一套托管类,使得这些托管类可以很容易地实现该操作。</P>
<P>
HttpListener:实现您自己的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器</P>
<P>System.Net 包含几个用来与 http.sys 进行交互的新类。HttpListener 是这些类中的关键一个。可以使用它来创建简单的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器(或侦听器),用于响应传入的 HTTP 请求。这个侦听器在 HttpListener 对象的生存期内都保持活动状态,不过您可以通过命令通知它开始和停止侦听。</P>
<P>要使用 HttpListener,必须先对它进行实例化。然后通过向 Prefixes 属性中添加 URL 前缀,来指示侦听器应该处理哪些 HTTP URL。每个 URI 必须包含一个方案(“http”或“https”)、主机、端口(可选)和路径(可选)。每个前缀都必须以正斜杠结尾: </P><PRE>HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://localhost:8081/foo/");
listener.Prefixes.Add("http://127.0.0.1:8081/foo/");
listener.Start();
</PRE>
<P>对于一个特定的 URL 前缀,只能有一个 HttpListener 在侦听它。如果您试图添加副本,就会得到 Win32Exception 异常。当您指定一个端口时,可以将主机名替换为“*”,以指示侦听器应该处理具有该端口的所有 URI,除非另一个 HttpListener 与它们匹配。或者可以将主机名替换为“+”,以指示侦听器接受对指定端口的所有请求,如下所示: </P>

韩冰 发表于 2005-1-16 11:19

<PRE>HttpListener listener = new HttpListener();listener.Prefixes.Add("http://+:8081/");listener.Start();</PRE><P>您也可以通过 AuthenticationScheme 属性指定侦听器所使用的身份验证方案。HttpListener 支持匿名、基本、简要和 Windows 身份验证。它也支持安全套接字层 (SSL) 连接,因此可以通过 HTTPS 安全地使用基本身份验证,如下所示: </P><PRE>HttpListener listener = new HttpListener();listener.AuthenticationSchemes = AuthenticationSchemes.Basic;listener.Prefixes.Add("https://+:8081/");listener.Start();</PRE><P>正如您刚刚看到的,一旦指定了侦听器要处理的 URI 前缀,就必须调用 Start 方法(请注意:在调用 Start 之前必须至少添加一个前缀)。Start 并没有真正做什么重要的事情 — 它只是简单地准备侦听器对象以开始接收请求。</P><P>要接收请求,就必须调用 GetContext,如下所示: </P><PRE>HttpListenerContext ctx = listener.GetContext();</PRE><P>GetContext 是一个同步调用,它在等待传入的请求到达时阻塞。直到接收到一个请求时,它才会返回。HttpListener 也通过 BeginGetContext 和 EndGetContext 提供异步接收请求机制。GetContext 和 EndGetContext 返回一个 HttpListenerContext 对象,该对象表示接收到的 HTTP 请求。 </P><P>您可以使用 HttpListener 将自己的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器与如<a href="http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx?fig=true#fig2" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>图 2</FONT></EM></A> 所示的示例应用程序相集成。您需要做的只是在您的<a href="http://hackbase.com/hacker" target="_blank" >代码</A>中将请求从 HttpListener 转发到 HTTP 管线。您可以添加一个循环,该循环不断地调用 GetContext,并使用返回的 HttpListenerContext 对象中的信息来调用 ProcessRequest。然后使用 HttpListenerContext 类来查找请求的文件名(使用 Request.Url.LocalPath 属性,如“/math.asmx”)和查询字符串(使用 Request.Url.Query 属性,如“?WSDL”)。使用该<a href="http://hackbase.com/hacker" target="_blank" >代码</A>,您就可以通过 HTTP 请求 ASP.NET 页,如<a href="http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx?fig=true#fig4" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>图 4</FONT></EM></A> 所示。</P><P>做出这些更改并运行程序之后,控制台应用程序就开始等待 GetContext 返回。现在您可以打开一个 Web 浏览器,并定位到注册的 URI(例如,http://localhost:8081/math.asmx)。这个操作完成后,GetContext 就会返回并将请求递交给 HTTP 管线。然后应该查看一下写入控制台窗口的响应,如前面所做的。</P><P>HttpListenerContext与 HttpContext 类似,它提供 Request、Response 和 User 属性,使得与 HTTP 消息的所有方面进行交互变得很容易。Request 属性的类型为 HttpListenerRequest,而 Response 属性的类型为 HttpListenerResponse。HttpListenerRequest 用于访问请求的 HTTP 方法、URL、标头、用户代理、主体及其他部分。HttpListenerResponse 用于将 HTTP 响应写回到客户端。User 属性返回 IPrincipal,它带有关于通过身份验证的用户的信息。</P><P>您可以使用这些属性进一步扩展这个示例,以便它能够直接写入 HTTP 响应流。可以这样来实现:修改 MySimpleHost.ProcessRequest 的签名,以使其接受一个 TextWriter。完成后,可以将 HttpListenerContext.Response.OutputStream 包装在 StreamWriter 对象中并将它传入。</P><DIV 300px"><img src="http://www1.hackbase.com/UpLoadFiles/NewsPhoto/SMXfig06.gif">
<P><B>图 6 浏览器输出</B></P><DIV class=figureRule></DIV></DIV><P><a href="http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx?fig=true#fig5" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>图 5</FONT></EM></A> 提供了修改后的示例的完整<a href="http://hackbase.com/hacker" target="_blank" >代码</A>,它集成了一个 HttpListener。现在运行示例时,就可以使用浏览器来读取并定位由 ASMX 生成的文档页面(请参见<B>图 6</B>)。每次应用程序接收到一个请求时,控制台窗口中都会打印出一条消息(请参见<B>图 7</B>)。</P><DIV 300px"><img src="http://www1.hackbase.com/UpLoadFiles/NewsPhoto/SMXfig07.gif">
<P><B>图 7 控制台应用程序输出</B></P><DIV class=figureRule></DIV></DIV><P>这个示例演示了一个可以处理 HTTP GET 请求和查询字符串的宿主模型。SimpleWorkerRequest 只是为处理这种简单情况而设计的,它不能处理更加高级的 POST 操作。因此,这个示例无法完全宿主 ASMX 终结点,ASMX 终结点需要有 POST 支持来处理传入的 SOAP 请求。</P><P>
宿主ASMX</P><P>要完全支持 ASMX 终结点,您需要一个知道如何处理请求/响应流的自定义 HttpWorkerRequest。它应该基于从 GetContext 获得的 HttpListenerContext 对象。这是个很棘手的任务,因为 HttpWorkerRequest 非常庞大,而且文档没有完全标准化。因此,我提供了一个名为 HttpListenerWorkerRequest 的示例实现(如<a href="http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx?fig=true#fig8" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>图 8</FONT></EM></A> 所示)。</P><P>此时,您可能会尝试回到前面的示例,将 SimpleWorkerRequest 的所有实例替换为 HttpListenerWorkerRequest。然而,这样做需要您将 HttpListenerContext 对象传入 ProcessRequest。遗憾的是,HttpListenerContext 不是从 MarshalByRefObject 派生的,从而阻止它跨 AppDomain 边界传递。要实现此目的,就需要重新设计这个示例。</P><P>首先,需要一个包装 HttpListener 对象的类,并使它可以跨 AppDomain 进行控制。我在<a href="http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx?fig=true#fig9" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>图 9</FONT></EM></A> 中提供了一个名为 HttpListenerWrapper 的类。这就是从现在起要在调用 CreateApplicationHost 时指定的类型。它有一个 Configure 方法,该方法可以实例化包含的 HttpListener 对象,并注册所提供的 URI 前缀。它具有 Start 和 Stop 方法,这两个方法简单委托给侦听器。它还有一个 ProcessRequest 方法来处理其他任何事情 — 调用 GetContext、实例化新的 HttpListenerWorkerRequest、并将其传入处理该请求的 HttpRuntime.ProcessRequest。您可以在宿主应用程序中使用以下类: </P><PRE>HttpListenerWrapper listener =      (HttpListenerWrapper)ApplicationHost.CreateApplicationHost(    typeof(HttpListenerWrapper), "/", Directory.GetCurrentDirectory());listener.Configure(prefixes, "/", Directory.GetCurrentDirectory());listener.Start();while (true) listener.ProcessRequest();</PRE><P>现在您就有了一个用于 ASMX 终结点的全功能宿主。提供的下载中还有另外一个完整的示例,它演示了这段<a href="http://hackbase.com/hacker" target="_blank" >代码</A>的操作。现在,当控制台应用程序运行时,就应该能够使用 SOAP 或者通过 HTML 文档页面提供的窗体调用 ASMX WebMethods。</P><P>
宿主模型:桌面上的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A></P><P>既然您知道了如何在选择的进程中宿主 ASMX,现在您大概最想知道应该在什么时候、什么地方使用这个<a href="http://hackbase.com/network" target="_blank" >技术</A>。在一台特殊的<a href="http://hackbase.com/skill" target="_blank" >计算机</A>上,由于各种情况而无法运行 IIS,不过您可能仍然想使用 ASMX <a href="http://hackbase.com/hacker/program" target="_blank" >编程</A>模型,以便在该节点上宿主 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>。如果是这种情况,本专栏所讨论的<a href="http://hackbase.com/network" target="_blank" >技术</A>就是一个很好的选择。</P><P>与 inetinfo.exe 不同(它提供许多用于不同通信类型的<a href="http://vip.hackbase.com/" target="_blank" >服务</A>),http.sys 是一个简化的内核,只对 HTTP 流量进行处理。因此它的<a href="http://hackbase.com/hacker" target="_blank" >攻击</A>面减少了。假如您在<a href="http://hackbase.com/skill" target="_blank" >计算机</A>上安装了 Windows <a href="http://hackbase.com/skill/XP" target="_blank" >XP</A> SP2 或 Windows Server 2003,您就可以在没有 IIS 的条件下,在自己的进程中宿主 ASMX。这意味着您可以根据自己的具体需要,在控制台应用程序、Windows 窗体应用程序或 Windows NT&reg; <a href="http://vip.hackbase.com/" target="_blank" >服务</A>中宿主 ASMX。</P><P>然而,我应该指出,当您采用这种方法时,您就放弃了 IIS 通过 w3wp.exe(或 aspnet<a href="http://www1.hackbase.com/network/network/200501169554_1.htm#" target="_blank" >_</A>wp.exe)辅助进程提供的高级进程模型。这意味着您失去了进程管理(启动、失败检测、回收)、线程池管理和 ISAPI 支持等一些功能。当您宿主 ASMX 时,您就提供了这个进程,因此您要负责提供进程模型和相关的<a href="http://vip.hackbase.com/" target="_blank" >服务</A>。</P><DIV 218px"><img src="http://www1.hackbase.com/UpLoadFiles/NewsPhoto/SMXfig10.gif">
<P><B>图 10 桌面上的 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A></B></P><DIV class=figureRule></DIV></DIV><P>在自己的进程中宿主 ASMX 时,最引人注意的情况也许就是需要在桌面上运行 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>的情况。例如,您可能有一个 Windows 窗体应用程序,它需要从一个 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器或其他某个内部<a href="http://hackbase.com/job" target="_blank" >企业</A>范围的 Windows <a href="http://vip.hackbase.com/" target="_blank" >服务</A>接收通知(请参见<B>图 10</B>)。在桌面上,您不需要像在<a href="http://vip.hackbase.com/" target="_blank" >服务</A>器上那样有一个高级的进程模型,但是利用 ASMX 的有效<a href="http://hackbase.com/hacker/program" target="_blank" >编程</A>模型还是有好处的。Http.sys 和 ASMX 宿主很适合于这种情况。我在下载中提供了其他一些示例(宿主 ASMX 的一个 Windows 窗体应用程序和一个 Windows <a href="http://vip.hackbase.com/" target="_blank" >服务</A>)来阐明这些概念。</P><P>
我们所处的位置</P><P>我介绍了在自己选择的进程中宿主 ASP.NET HTTP 管线的基本<a href="http://hackbase.com/network/zs" target="_blank" >知识</A>。同时还讨论了如何利用 http.sys 和新的 HttpListener 托管类(和相关的类)来为您的应用程序构建 Web <a href="http://vip.hackbase.com/" target="_blank" >服务</A>器。HttpListener 使得接收 HTTP 消息并将它们转发给 ASP.NET 页面以进行处理变得很容易。使用这些<a href="http://hackbase.com/network" target="_blank" >技术</A>,您可以很灵活地在任何地方运行 ASMX。</P><P>有关这个主题的更多信息,请参阅“<a href="http://msdn.microsoft.com/library/en-us/dnvs05/html/wsnetfx2.asp" target="_blank" >_</A>blank&gt;<FONT color=#0000ff><EM>New Features for Web Service Developers in Beta 1 of the .NET Framework </EM><EM>2.0</EM></FONT></A>”、“<a href=" target="_blank" >iis</A>RG<a href="http://www1.hackbase.com/network/network/200501169554_1.htm#" target="_blank" >_</A>SCA<a href="http://www1.hackbase.com/network/network/200501169554_1.htm#" target="_blank" >_</A>24.mspx" target=<a href="http://www1.hackbase.com/network/network/200501169554_1.htm#" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>HTTP.sys Response Cache</FONT></EM></A>”和“<a href="http://www.asp.net/projects/cassini/download" target="_blank" >_</A>blank&gt;<EM><FONT color=#0000ff>Download ASP.NET Cassini Sample Web Server</FONT></EM></A>”。</P>
页: [1]
查看完整版本: 在没有 IIS 的条件下运行 ASMX