利用SelfHost实现小型HTTP服务器

本文详细介绍如何使用.NET Framework自建HTTP服务,包括创建控制台项目、添加Nuget包、配置WebAPI、实现静态文件处理及跨域支持。通过具体代码实例展示如何搭建一个完整的HTTP服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.创建应用,可以是Winform,WPF或者控制台的应用
创建控制台项目
创建控制台应用


 2.从Nuget添加下列引用
   (1) Microsoft.AspNet.Cors 
   (2) Microsoft.AspNet.WebApi.Core

   (3) Microsoft.Owin

   (4) Newtonsoft.Json
   (5)  Microsoft.AspNet.WebApi.Owin

   (6)  Microsoft.AspNet.WebApi.Cors
   (7)  Microsoft.AspNet.WebApi.WebHost
   (8)  Microsoft.AspNet.WebApi.SelfHost

   (9) Microsoft.Owin.Host.HttpListener

   (10) Microsoft.Owin.Hosting
 安装这些包时,其依赖项也一并安装.
安装依赖库
安装依赖库
依赖库安装完毕后
依赖库安装完毕后


 安装完毕后,package.config内容如下:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.Cors" version="5.2.6" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.6" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.6" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.SelfHost" version="5.2.6" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.6" targetFramework="net452" />
  <package id="Microsoft.Owin" version="4.0.0" targetFramework="net452" />
  <package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net452" />
  <package id="Microsoft.Owin.Hosting" version="4.0.0" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net452" />
  <package id="Owin" version="1.0" targetFramework="net452" />
</packages>

3.接下来,在项目中创建目录WebApi

4.在WebApi下创建目录controllers
创建文件夹
创建文件夹

5.在WebApi下新建类Startup,内容如下:

 

    using Microsoft.Owin;
    using Owin;
    using System;
    using System.IO;
    using System.Net.Http.Formatting;
    using System.Threading.Tasks;
    using System.Web.Http;
    using System.Web.Http.Cors;
     
    namespace HttpSelfHost.WebApi
    {
     
        class Startup
        {
            private static string _siteDir =
                   System.Configuration.ConfigurationManager.AppSettings.Get("SiteDir");
            public void Configuration(IAppBuilder app)
            {
                // web api 接口
                HttpConfiguration config = InitWebApiConfig();
                app.UseWebApi(config);
                //静态文件
                app.Use((context, fun) =>
                {
                    return StaticWebFileHandel(context, fun);
                });
            }
            /// <summary>
            /// 路由初始化
            /// </summary>
            public HttpConfiguration InitWebApiConfig()
            {
                HttpConfiguration config = new HttpConfiguration();
                config.Routes.MapHttpRoute(
                    name: "Default",
                    routeTemplate: "api/{controller}/{action}",
                    defaults: new { id = RouteParameter.Optional }
                );
                // 配置 http 服务的路由
                var cors = new EnableCorsAttribute("*", "*", "*");//跨域允许设置
                config.EnableCors(cors);
     
                config.Formatters
                   .XmlFormatter.SupportedMediaTypes.Clear();
                //默认返回 json
                config.Formatters
                    .JsonFormatter.MediaTypeMappings.Add(
                    new QueryStringMapping("datatype", "json", "application/json"));
                //返回格式选择
                config.Formatters
                    .XmlFormatter.MediaTypeMappings.Add(
                    new QueryStringMapping("datatype", "xml", "application/xml"));
     
                //json 序列化设置
                config.Formatters
                    .JsonFormatter.SerializerSettings = new
                    Newtonsoft.Json.JsonSerializerSettings()
                    {
                        //NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
                        DateFormatString = "yyyy-MM-dd HH:mm:ss" //设置时间日期格式化
                    };
                return config;
            }
            /// <summary>
            /// 客户端请求静态文件处理
            /// </summary>
            /// <param name="context"></param>
            /// <param name="next"></param>
            /// <returns></returns>
            public Task StaticWebFileHandel(IOwinContext context, Func<Task> next)
            {
                //获取物理文件路径
                var path = GetFilePath(context.Request.Path.Value);
                //验证路径是否存在
                if (!File.Exists(path) && !path.EndsWith("html"))
                {
                    path += ".html";
                }
                if (File.Exists(path))
                {
                    return SetResponse(context, path);
                }
                //不存在返回下一个请求
                return next();
            }
            public static string GetFilePath(string relPath)
            {
                if (relPath.IndexOf("index") > -1)
                {
                    String temp = relPath;
                }
                var basePath = AppDomain.CurrentDomain.BaseDirectory;
                var filePath = relPath.TrimStart('/').Replace('/', '\\');
                if (_siteDir == ".")
                {
                    return Path.Combine(basePath, filePath);
                }
                else
                {
                    return Path.Combine(
                      AppDomain.CurrentDomain.BaseDirectory
                      , _siteDir == "." ? "" : _siteDir
                      , relPath.Replace('/', '\\')).TrimStart('\\');
                }
            }
     
            public Task SetResponse(IOwinContext context, string path)
            {
                /*
                    .txt text/plain
                    RTF文本 .rtf application/rtf
                    PDF文档 .pdf application/pdf
                    Microsoft Word文件 .word application/msword
                    PNG图像 .png image/png
                    GIF图形 .gif image/gif
                    JPEG图形 .jpeg,.jpg image/jpeg
                    au声音文件 .au audio/basic
                    MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
                    RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
                    MPEG文件 .mpg,.mpeg video/mpeg
                    AVI文件 .avi video/x-msvideo
                    GZIP文件 .gz application/x-gzip
                    TAR文件 .tar application/x-tar
                    任意的二进制数据 application/octet-stream
                 */
                var perfix = Path.GetExtension(path);
                if (perfix == ".html")
                    context.Response.ContentType = "text/html; charset=utf-8";
                else if (perfix == ".txt")
                    context.Response.ContentType = "text/plain";
                else if (perfix == ".js")
                    context.Response.ContentType = "application/x-javascript";
                else if (perfix == ".css")
                    context.Response.ContentType = "text/css";
                else
                {
                    if (perfix == ".jpeg" || perfix == ".jpg")
                        context.Response.ContentType = "image/jpeg";
                    else if (perfix == ".gif")
                        context.Response.ContentType = "image/gif";
                    else if (perfix == ".png")
                        context.Response.ContentType = "image/png";
                    else if (perfix == ".svg")
                        context.Response.ContentType = "image/svg+xml";
                    else if (perfix == ".woff")
                        context.Response.ContentType = "application/font-woff";
                    else if (perfix == ".woff2")
                        context.Response.ContentType = "application/font-woff2";
                    else if (perfix == ".ttf")
                        context.Response.ContentType = "application/octet-stream";
     
                    return context.Response.WriteAsync(File.ReadAllBytes(path));
                }
                //truetype
                return context.Response.WriteAsync(File.ReadAllText(path));
            }
        }
    }

  这里需要添加引用:System.Configuration:
添加System.Configuration引用
添加System.Configuration引用

5.在WebApi下新建类WebServer,内容如下:

    using System;
    using Microsoft.Owin.Hosting;
     
    namespace HttpSelfHost.WebApi
    {
        public class WebServer
        {
            static IDisposable server = null;
            public static event EventHandles.MessageEventHandle MessageEvent = null;
            public static void Start()
            {
                StartOptions opt = new StartOptions();
                opt.Port = int.Parse(System.Configuration.ConfigurationManager.AppSettings.Get("Port"));
                string baseAddress = string.Format("http://{0}:{1}/",
                       "*",
                       System.Configuration.ConfigurationManager.AppSettings.Get("Port"));
                server = WebApp.Start<Startup>(url: baseAddress);
                MessageEvent?.Invoke(String.Format("host 已启动:{0}", baseAddress));
            }
        }
    }

6. App.config中添加配置节

  <appSettings>
    <add key="Domain" value="localhost" />
    <add key="port" value="9000" />
    <add key="SiteDir" value="." />
  </appSettings>

     其中的port为HttpSelfHost监听的端口
App.config内容
App.config内容

7.在controllers目录下创建控制器DemoController,然后添加几个方法:

    using HttpSelfHost.model;
    using System;
    using System.Collections.Generic;
    using System.Web.Http;
     
    namespace HttpSelfHost.WebApi.controllers
    {
        public class DemoController:ApiController
        {
            [HttpGet]
            [HttpPost]
            public dynamic allStudents()
            {
                return new
                {
                    result = true,
                    desc =  "请求成功",
                    data = new List<StudentInfo>()
                    {
                        new StudentInfo
                        {
                            ClassId="ClassID982712311231",
                            Sex="男",
                            StudentId=Guid.NewGuid().ToString(),
                            StudentName="男学生一枚",
                            StudentNumber="XH2018090001"
                        },
                        new StudentInfo
                        {
                            ClassId="ClassID982712311232",
                            Sex="女",
                            StudentId=Guid.NewGuid().ToString(),
                            StudentName="女学生一枚",
                            StudentNumber="XH2018090002"
                        }
                    }
                };
            }
            [HttpGet]
            [HttpPost]
            public dynamic queryStudents([FromBody]string name)
            {
                return new
                {
                    result = true,
                    desc = "查询请求成功,参数name:"+name,
                    data = new List<StudentInfo>()
                    {
                        new StudentInfo
                        {
                            ClassId="ClassID982712311231",
                            Sex="男",
                            StudentId=Guid.NewGuid().ToString(),
                            StudentName="男学生一枚",
                            StudentNumber="XH2018090001"
                        },
                        new StudentInfo
                        {
                            ClassId="ClassID982712311232",
                            Sex="女",
                            StudentId=Guid.NewGuid().ToString(),
                            StudentName="女学生一枚",
                            StudentNumber="XH2018090002"
                        }
                    },
                    page=1,
                    total=2,
                    pageCount=1
                };
            }
            [HttpGet]
            [HttpPost]
            public dynamic saveStudents([FromBody]StudentInfo info)
            {
                info.StudentId = Guid.NewGuid().ToString();
                return new
                {
                    result = true,
                    desc = "保存成功,学生姓名:" + info.StudentName,
                    data = info.StudentId
                };
            }
        }
    }

添加控制器

8. 接下来就可以在应用中启动HTTP服务了:

    using System;
     
    namespace HttpSelfHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                StartServer();
                String inputStr = null;
                while ((inputStr = Console.ReadLine()).ToLower() != "exit")
                {
     
                }
            }
            static public void StartServer()
            {
                WebApi.WebServer.MessageEvent += WebServer_MessageEvent;
                WebApi.WebServer.Start();
            }
     
            private static void WebServer_MessageEvent(string msg)
            {
                Console.WriteLine(msg);
            }
        }
    }

运行一下:
运行SelfHostHttp
运行SelfHostHttp

我们在浏览器中测试一下接口:
Get测试
Get测试

带参数Get测试
Post测试
Post测试
Post对象提交
Post对象提交
Post对象提交
Post对象提交

 

接下来,我们测试静态文件请求

9.在生成的输出目录创建文件夹HttpPages:
创建静态文件目录
创建静态文件目录

10. 然后将HTML文件和需要的CSS,JS一股脑儿拷贝进去:

11.在VS的解决方案管理器中,点击右上角的"显示所有文件":

然后展开bin/Debug,右键选择HttpPages,弹出的菜单中选择"包括在项目中":

在pages目录下添加一个测试的html文件,包含vue,iview等脚本和css,注意引用的相对位置:

OK,接下来启动程序,看看打开网页是什么情况:
静态文件请求
静态文件请求

 

看起来还不错.

其中部分代码参考了本站许多大神的帖子,希望大神看到后留下帖子地址,本人可以修改帖子具名出处.
--------------------- 
作者:tujun 
来源:优快云 
原文:https://blog.youkuaiyun.com/tujun/article/details/83686407 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值