多想想,总能感悟出什么...

机会就是这么产生的!

在应用程序中集成支持ASP.NET/WebService 的WebServer

某些时候我们需要在没有 IIS 的环境运行 ASP.NET/WebService,诸如 Windows XP Home 操作系统,演示光盘等。幸好 .NET Framework 2.0 为我们提供了新的功能,让我们非常方便地在我们程序内部集成一个简便的 WebServer。

1. 创建 ASP.NET 宿主

在 .NET Framework 2.0 中新增了 System.Web.Hosting 名字空间,我们要用到的有 ApplicationHost、HttpRuntime 和一个从 HttpWorkerRequest 派生的类。

(1) 利用 ApplicationHost.CreateApplicationHost() 创建并配置用于承载 ASP.NET 的应用程序域。
(2) 创建继承自 HttpWorkerRequest 的类型,承载 ASP.NET 应用程序,处理请求页面,返回页面执行结果。
(3) 调用 HttpRuntime.ProcessRequest() 方法完成整个请求过程。

ApplicationHost.CreateApplicationHost() 需要我们提供一个自定义类型,该类型用来在 ASP.NET 程序域和进程缺省程序域间进行交互和通讯。由于需要跨域操作,因此该类型必须直接或间接继承自 MarshalByRefObject。另外,我们还要提供虚拟目录和存放 .aspx/.asmx 页面的物理路径参数。

下面的演示中,我们使用 Framework 提供的 SimpleWorkerRequest 来处理页面请求。

test.aspx
The current time is <%=DateTime.Now.ToString()%>.

TestHost.cs
using System.Web;
using System.Web.Hosting;

public class MyHost : MarshalByRefObject
{
  public void ProcessRequest(string page, string query, TextWriter output)
  {
    SimpleWorkerRequest simple = new SimpleWorkerRequest(page, query, output);
    HttpRuntime.ProcessRequest(simple);
  }
}

public class Program
{
  static void Main(string[] args)
  {
    MyHost host = (MyHost)ApplicationHost.CreateApplicationHost(typeof(MyHost), "/", @"D:\TestWeb");
    
    // 发出请求 "test.aspx",将页面结果输出到控制台窗口。
    host.ProcessRequest("test.aspx", "", Console.Out);

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey(true);
  }
}

运行该程序,我们会发现 test.aspx 页面结果正常输出。

需要注意的是,编译的程序集文件必须放在 GAC 或者页面物理路径的 bin 子目录中(如:D:\TestWeb\bin\TestHost.exe),否则运行时会触发 FileNotFoundException 异常。

2. 创建 Http Listener

除了 ASP.NET 宿主,我们还需要创建一个监听处理 Http 请求的 Listener。System.Net.HttpListener 提供了一个简单的、可通过编程方式控制的 HTTP 协议侦听器,不过该类仅在运行 Windows XP SP2 或 Windows Server 2003 操作系统的计算机上可用(可使用 IsSupported 属性判断)。

下面的例子中,我们监听 8080 端口的所有请求。分解请求信息后输出页面内容。
using System.Net;

if (HttpListener.IsSupported)
{
  HttpListener listener = new HttpListener();
  listener.Prefixes.Add("http://+:8080/");
  listener.Start();

  while (true)
  {
    HttpListenerContext context = listener.GetContext();

    string page = context.Request.Url.LocalPath.Replace("/", "");
    string query = context.Request.Url.Query.Replace("?", "");
    Console.WriteLine("接收到请求:{0}?{1}", page, query);

    StreamWriter sw = new StreamWriter(context.Response.OutputStream);

    sw.WriteLine("<html>");
    sw.WriteLine("Hello, World!<br>");
    sw.WriteLine(string.Format("OriginalString:{0}<br>", context.Request.Url.OriginalString));
    sw.WriteLine(string.Format("LocalPath:{0}<br>", context.Request.Url.LocalPath));
    sw.WriteLine(string.Format("Query:{0}<br>", context.Request.Url.Query));
    sw.WriteLine("</html>");

    sw.Flush();
    context.Response.Close();
  }
}

有关 HttpListener 的详细信息可参考 MSDN 文档。

3. 创建可运行 ASP.NET/WebService 的 WebServer

综合上面的内容,我们就可以得到所需的 WebServer 了。
运行下面的程序,然后在浏览器中输入 "http://localhost:8080/test.aspx" 看看结果。 [smile]
using System.Web;
using System.Web.Hosting;
using System.Net;

public class MyHost : MarshalByRefObject
{
  public void ProcessRequest(string page, string query, TextWriter output)
  {
    SimpleWorkerRequest simple = new SimpleWorkerRequest(page, query, output);
    HttpRuntime.ProcessRequest(simple);
  }
}

public class Program
{
  static void Main(string[] args)
  {
    MyHost host = (MyHost)ApplicationHost.CreateApplicationHost(typeof(MyHost), "/", @"D:\TestWeb");

    if (HttpListener.IsSupported)
    {
      HttpListener listener = new HttpListener();
      listener.Prefixes.Add("http://+:8080/");
      listener.Start();

      while (true)
      {
        HttpListenerContext context = listener.GetContext();

        string page = context.Request.Url.LocalPath.Replace("/", "");
        string query = context.Request.Url.Query.Replace("?", "");
        Console.WriteLine("接收到请求:{0}?{1}", page, query);

        StreamWriter sw = new StreamWriter(context.Response.OutputStream);
        host.ProcessRequest(page, query, sw);
        sw.Flush();
        context.Response.Close();
      }
    }

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey(true);
  }
}

--------

附:更详细信息可参考 《在没有 IIS 的条件下运行 ASMX》。

posted on 2008-02-03 13:39  XiaoShan  阅读(677)  评论(0编辑  收藏  举报

导航