.NET Framework 自托管详解

.NET Framework 自托管详解

自托管(Self-Hosting)是指不依赖 IIS 等外部 Web 服务器,而是通过应用程序自身创建和管理 Web 服务器实例的方式运行 Web 应用程序。

1. HttpListener 方式

这是最基础的自托管方式,使用 .NET Framework 内置的 HttpListener 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // 创建 HttpListener 实例
        HttpListener listener = new HttpListener();
        
        // 添加监听的 URL 前缀
        listener.Prefixes.Add("http://localhost:8080/");
        
        // 启动监听
        listener.Start();
        Console.WriteLine("服务器启动,监听 http://localhost:8080/");
        
        // 处理请求循环
        while (true)
        {
            // 等待请求
            HttpListenerContext context = await listener.GetContextAsync();
            
            // 处理请求
            await ProcessRequest(context);
        }
    }
    
    static async Task ProcessRequest(HttpListenerContext context)
    {
        HttpListenerResponse response = context.Response;
        
        // 设置响应内容
        string responseString = "<html><body><h1>Hello from Self-Hosted Server!</h1></body></html>";
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
        
        // 设置响应头
        response.ContentType = "text/html";
        response.ContentLength64 = buffer.Length;
        
        // 写入响应
        using (Stream output = response.OutputStream)
        {
            await output.WriteAsync(buffer, 0, buffer.Length);
        }
        
        // 关闭响应
        response.Close();
    }
}

2. ASP.NET Web API 自托管

使用 Microsoft.AspNet.WebApi.SelfHost 包可以创建更完整的 Web API 服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.Web.Http;
using System.Web.Http.SelfHost;

class Program
{
    static void Main(string[] args)
    {
        // 配置 HTTP 服务器
        var config = new HttpSelfHostConfiguration("http://localhost:8080");
        
        // 配置路由
        config.Routes.MapHttpRoute(
            "Default",
            "{controller}/{id}",
            new { id = RouteParameter.Optional }
        );
        
        // 创建并启动服务器
        using (HttpSelfHostServer server = new HttpSelfHostServer(config))
        {
            server.OpenAsync().Wait();
            Console.WriteLine("Web API 服务器启动,监听 http://localhost:8080/");
            Console.WriteLine("按任意键退出...");
            Console.ReadKey();
        }
    }
}

// 控制器示例
public class ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
    
    public string Get(int id)
    {
        return "value";
    }
}

3. OWIN 自托管

OWIN (Open Web Interface for .NET) 提供了更灵活的中间件架构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using Microsoft.Owin.Hosting;
using Owin;
using System.Web.Http;

class Program
{
    static void Main(string[] args)
    {
        string baseAddress = "http://localhost:8080/";
        
        // 启动 OWIN 主机
        using (WebApp.Start<Startup>(url: baseAddress))
        {
            Console.WriteLine("OWIN 服务器启动,监听 " + baseAddress);
            Console.WriteLine("按任意键退出...");
            Console.ReadKey();
        }
    }
}

public class Startup
{
    public void Configuration(IAppBuilder appBuilder)
    {
        // 配置 Web API
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            name: "Default",
            routeTemplate: "{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        
        appBuilder.UseWebApi(config);
    }
}

4. WCF 服务自托管

WCF 服务也可以自托管运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.ServiceModel;
using System.ServiceModel.Web;

[ServiceContract]
public class MyService
{
    [OperationContract]
    [WebGet(UriTemplate = "/hello?name={name}", ResponseFormat = WebMessageFormat.Json)]
    public string SayHello(string name)
    {
        return $"Hello, {name}!";
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 创建 WebServiceHost
        WebServiceHost host = new WebServiceHost(typeof(MyService), 
            new Uri("http://localhost:8080/MyService"));
        
        try
        {
            // 打开服务
            host.Open();
            Console.WriteLine("WCF REST 服务启动,监听 http://localhost:8080/MyService");
            Console.WriteLine("按任意键退出...");
            Console.ReadKey();
            
            // 关闭服务
            host.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"错误: {ex.Message}");
            host.Abort();
        }
    }
}

自托管的优势

  1. 独立部署:不需要安装和配置 IIS
  2. 控制性强:完全控制服务器启动、配置和生命周期
  3. 开发便捷:简化开发和测试流程
  4. 资源占用少:相比完整 IIS 更轻量级
  5. 跨平台兼容性:某些方式可以在 Mono 上运行

自托管的限制

  1. 功能限制:缺少 IIS 的高级功能(如应用程序池管理、SSL 配置等)
  2. 安全性:需要自行处理安全相关配置
  3. 性能优化:不如 IIS 经过充分优化
  4. 管理工具:缺少 IIS 提供的图形化管理界面

自托管特别适合开发环境、微服务架构、Windows 服务集成等场景。