//http服务路由
 Dictionary<string, string> routes = new Dictionary<string, string> {
    {"/index","IndexController"},
 //服务对象
 MyHttpServer httpServer;
 //启动http服务
httpServer = new MyHttpServer(routes);//初始化,传入路由
httpServer.respNotice += dataHandle;//回调方法,接收到http请求时触发
httpServer.Start(12333);//端口
  /// <summary>
  /// 收到请求的回调函数
   /// </summary>
   /// <param name="data">客户端请求的数据</param>
   /// <param name="resp">respon对象</param>
   /// <param name="route">网址路径,如/api/test</param>
   /// <param name="request_type">请求类型,get或者post</param>
   public void dataHandle(Dictionary<string, string> data, HttpListenerResponse resp, string route = "", string request_type = "get")
       string controller = routes.ContainsKey(route) ? routes[route] : "";
	  //预定义返回的json数据
       Dictionary<string, string> resp_data = new Dictionary<string, string>();
       resp_data.Add("code", "1");
       resp_data.Add("data", "");
       resp_data.Add("time", "12345");
       resp_data.Add("msg", "ok ");
	   //根据路由key的val匹配相应的算法,以下是自己的逻辑
       switch (controller)
           case "IndexController":
               resp_json = JsonConvert.SerializeObject(resp_data);
               //输出结果
               httpServer.responData(resp_json, resp);
               break;
           default:
               httpServer.responData("404", resp);
               break;

MyHttpServer.cs

using HttpListenerPost;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PaddleOcrService.request.myhttp
    public class MyHttpServer
        //创建委托。用于通知
        public delegate void respNoticeDelegate(Dictionary<string, string> data, HttpListenerResponse resp,string route,string request_type = "get");
        public event respNoticeDelegate respNotice;
        private HttpListener listener = new HttpListener();
        private Dictionary<string, string> actionDict = new Dictionary<string, string>();
        private ReturnDataBase respObj;//返回的数据
        public string curr_path = "";
        //接收到的数据
        public Dictionary<string, string> data_rec = new Dictionary<string, string>();
        public MyHttpServer(Dictionary<string,string> routes = null)
            if(routes != null)
                //遍历字典路由
                foreach (KeyValuePair<string, string> kvp in routes)
                    AddPrefixes(kvp.Key, kvp.Value);
        public void AddPrefixes(string url, string action)
            actionDict.Add(url, action);
        public void close()
            listener.Stop();//停止监听
            //listener.Close();//释放资源
        //开始监听
        public void Start(int port)
            if (!HttpListener.IsSupported)
                Console.WriteLine("无法在当前系统上运行服务(Windows XP SP2 or Server 2003)。" + DateTime.Now.ToString());
                return;
            if (actionDict.Count <= 0)
                System.Console.WriteLine("没有监听端口");
            //监听url
            foreach (var item in actionDict)
                var url = string.Format("http://127.0.0.1:{0}{1}", port, item.Key + "/");
                System.Console.WriteLine(url);
                listener.Prefixes.Add(url);  //监听的是以item.Key + "/"+XXX接口
            listener.Start();
            listener.BeginGetContext(Result, null);
            respObj = new ReturnDataBase();
            System.Console.WriteLine("开始监听");
            System.Console.Read();
        private void Result(IAsyncResult asy)
            if (!listener.IsListening) return;//如果已经停止监听了就直接返回
            listener.BeginGetContext(Result, null);
            var context = listener.EndGetContext(asy);
            var req = context.Request;
            var rsp = context.Response;
            //对接口url处理,解析出curr_path也就是当前路由
            string route=HandlerReq(req.RawUrl);//获取当前路由
            //对接口所传数据处理
            Dictionary<string, string> data = new Dictionary<string, string>();
            data= HandleHttpMethod(context,rsp,route);
            //将解析后的结果 通知
            dataNoticeEvent(data,rsp, route, context.Request.HttpMethod);
        /// <summary>
        /// 输出结果(返回结果)
        /// </summary>
        /// <param name="content">结果</param>
        /// <param name="rsp">httprespon对象</param>
        /// <returns></returns>
        public string responData(string content,HttpListenerResponse rsp)
                using (var stream = rsp.OutputStream)
                    获取类名和方法名 格式: class.method
                    //string class_name = actionDict.ContainsKey(route) ? actionDict[route] : "";
                    /传入类名,利用反射创建对象并返回的数据,要返回给接口的
                    //string content = respObj.GetDataMain(class_name, data);
                    // response的outputStream输出数据的问题
                    //方法一:程序以什么码表输出,一定要控制浏览器以什么码表打开
                    //若"text/html;charset=UTF-8"写错,浏览器会提示下载
                    rsp.StatusCode = 200;
                    rsp.ContentType = "text/html;charset=UTF-8";//告诉客户端返回的ContentType类型为纯文本格式,编码为UTF-8
                    rsp.AddHeader("Content-type", "application/json");//添加响应头信息
                    rsp.ContentEncoding = Encoding.UTF8;
                    rsp.AppendHeader("Access-Control-Allow-Origin", "*");//允许跨域
                    rsp.AppendHeader("Access-Control-Allow-Credentials", "true");
                    //后台跨域请求;//允许跨域
                    //后台跨域请求,必须配置
                    rsp.AppendHeader("Access-Control-Allow-Headers", "Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With");
                    rsp.AppendHeader("Access-Control-Max-Age", "86400");
                    byte[] dataByte = Encoding.UTF8.GetBytes(content);
                    stream.Write(dataByte, 0, dataByte.Length);
                    stream.Close();
            catch (Exception e)
                rsp.Close();
                return e.Message;
            rsp.Close();
            return "";
        /// <summary>
        /// 对客户端来的url处理
        /// </summary>
        /// <param name="url"></param>
        private string HandlerReq(string url)
                //url : /test?a=1
                System.Console.WriteLine("url : " + url);
                string[] arr_str= url.Split('?');
                if(arr_str.Length > 0)
                    return curr_path = arr_str[0];//  如下:/api/test
                return "";
            catch (Exception e)
                return "";
        //处理接口所传数据 Post和Get 获取数据
        private Dictionary<string,string> HandleHttpMethod(HttpListenerContext context, HttpListenerResponse resp,string route)
            Dictionary<string, string> return_data = new Dictionary<string, string>();
            data_rec.Clear();//先清空上一次http接收的数据
            string contentType = context.Request.ContentType == null ? "" : context.Request.ContentType;
            //1. ContentType = multipart/form-data
            if (contentType.Contains("multipart/form-data") )
                //新建解析类(解析post数据)
                HttpListenerPostParaHelper parse = new HttpListenerPostParaHelper(context);
                List<HttpListenerPostValue> list = parse.GetHttpListenerPostValue();
                foreach (HttpListenerPostValue item in list)
                    string k = item.name;
                    string value = "";
                    if (item.type == 0)
                        //文本解析
                         value = Encoding.UTF8.GetString(item.datas).Replace("\r\n", "");
                        //byte数组转文件
                        File.WriteAllBytes(@"D:\test.png", item.datas);
                        value = @"D:\test.png";
                    dataRecAdd(k,value);
                return_data = data_rec;
                return return_data;
            //2.ContentType=application/json
            if (contentType.Contains("application/json"))
                    Stream stream = context.Request.InputStream;
                    StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                    string json = reader.ReadToEnd();
                    Dictionary<string, string> DicContent = new Dictionary<string, string>();
                    if (string.IsNullOrEmpty(json)) return return_data ;
                    if (json == "[]" || json == "") return return_data;
                    data_rec = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
                    return_data = data_rec;//返回的数据
                catch (Exception ex)
                    return return_data;
                return return_data;
                    var data = context.Request.QueryString;
                    // 没解决乱码问题,用url进行解析正常
                    string url = context.Request.Url.ToString();
                    string[] pars = url.Split('?');
                    string content = "";
                    if (pars.Length == 0)
                        return return_data;
                    if (pars.Length <= 1) return return_data;
                    string canshus = pars[1];
                    if (canshus.Length > 0)
                        string[] canshu = canshus.Split('&');
                        foreach (string i in canshu)
                            string[] messages = i.Split('=');
                            dataRecAdd(messages[0], messages[1]);
                            //content += "参数为:" + messages[0] + " 值为:" + messages[1];
                        return_data = data_rec;
                    return return_data;
                    break;
            return return_data;
        /// <summary>
        /// 将解析后的数据通知事件
        /// </summary>
        /// <param name="data">解析后的字典数据</param>
        /// <param name="rsp">respon对象</param>
        /// <param name="route">路由</param>
        /// <param name="method">方法</param>
        public void dataNoticeEvent(Dictionary<string, string> data,HttpListenerResponse rsp,string route, string method = "unkonwn")
            //if (data_rec.Count > 1)
            //    respNotice?.Invoke(data_rec, rsp,route,method);
            respNotice?.Invoke(data, rsp, route, method);
        public void dataRecAdd(string k ,string v)
            if (data_rec.ContainsKey(k))
                data_rec[k] = v;
                data_rec.Add(k, v);
    class ReturnDataBase
        public string GetDataMain(string class_method, Dictionary<string, string> rec_data)
            string[] class_arr = class_method.Split('.');//分割类名跟方法
            string class_name,method;
            if (class_arr.Length == 1) class_name = class_arr[0];
            if (class_arr.Length == 2) method = class_arr[1];
            if (class_arr.Length == 0) return "";
            return "cesh";

这个类主要用于解析content-type为multipart/form-data时解析数据

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace HttpListenerPost
    /// <summary>
    /// HttpListenner监听Post请求参数值实体
    /// </summary>
    public class HttpListenerPostValue
        /// <summary>
        /// 0=> 参数
        /// 1=> 文件
        /// </summary>
        public int type = 0;
        public string name;
        public byte[] datas;
    /// <summary>
    /// 获取Post请求中的参数和值帮助类
    /// </summary>
    public class HttpListenerPostParaHelper
        private HttpListenerContext request;
        public HttpListenerPostParaHelper(HttpListenerContext request)
            this.request = request;
        private bool CompareBytes(byte[] source, byte[] comparison)
                int count = source.Length;
                if (source.Length != comparison.Length)
                    return false;
                for (int i = 0; i < count; i++)
                    if (source[i] != comparison[i])
                        return false;
                return true;
            catch
                return false;
        private byte[] ReadLineAsBytes(Stream SourceStream)
            var resultStream = new MemoryStream();
            while (true)
                int data = SourceStream.ReadByte();
                resultStream.WriteByte((byte)data);
                if (data == 10)
                    break;
            resultStream.Position = 0;
            byte[] dataBytes = new byte[resultStream.Length];
            resultStream.Read(dataBytes, 0, dataBytes.Length);
            return dataBytes;
        /// <summary>
        /// 获取Post过来的参数和数据
        /// </summary>
        /// <returns></returns>
        public List<HttpListenerPostValue> GetHttpListenerPostValue()
                List<HttpListenerPostValue> HttpListenerPostValueList = new List<HttpListenerPostValue>();
                if (request.Request.ContentType.Length > 20 && string.Compare(request.Request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0)
                    string[] HttpListenerPostValue = request.Request.ContentType.Split(';').Skip(1).ToArray();
                    string boundary = string.Join(";", HttpListenerPostValue).Replace("boundary=", "").Trim();
                    byte[] ChunkBoundary = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
                    byte[] EndBoundary = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
                    Stream SourceStream = request.Request.InputStream;
                    var resultStream = new MemoryStream();
                    bool CanMoveNext = true;
                    HttpListenerPostValue data = null;
                    while (CanMoveNext)
                        byte[] currentChunk = ReadLineAsBytes(SourceStream);
                        if (!Encoding.UTF8.GetString(currentChunk).Equals("\r\n"))
                            resultStream.Write(currentChunk, 0, currentChunk.Length);
                        if (CompareBytes(ChunkBoundary, currentChunk))
                            byte[] result = new byte[resultStream.Length - ChunkBoundary.Length];
                            resultStream.Position = 0;
                            resultStream.Read(result, 0, result.Length);
                            CanMoveNext = true;
                            if (result.Length > 0)
                                data.datas = result;
                            data = new HttpListenerPostValue();
                            HttpListenerPostValueList.Add(data);
                            resultStream.Dispose();
                            resultStream = new MemoryStream();
                        else if (Encoding.UTF8.GetString(currentChunk).Contains("Content-Disposition"))
                            byte[] result = new byte[resultStream.Length - 2];
                            resultStream.Position = 0;
                            resultStream.Read(result, 0, result.Length);
                            CanMoveNext = true;
                            data.name = Encoding.UTF8.GetString(result).Replace("Content-Disposition: form-data; name=\"", "").Replace("\"", "").Split(';')[0];
                            resultStream.Dispose();
                            resultStream = new MemoryStream();
                        else if (Encoding.UTF8.GetString(currentChunk).Contains("Content-Type"))
                            CanMoveNext = true;
                            data.type = 1;
                            resultStream.Dispose();
                            resultStream = new MemoryStream();
                        else if (CompareBytes(EndBoundary, currentChunk))
                            byte[] result = new byte[resultStream.Length - EndBoundary.Length - 2];
                            resultStream.Position = 0;
                            resultStream.Read(result, 0, result.Length);
                            data.datas = result;
                            resultStream.Dispose();
                            CanMoveNext = false;
                return HttpListenerPostValueList;
            catch (Exception ex)
                return null;
2. 在项目中添加一个新的类文件(.cs),该文件将包含Web API的控制器代码。
3. 在控制器类中,使用System.Web.Http命名空间并继承ApiController类。
4. 在控制器类中,创建要公开的API方法。你可以使用各种HTTP动词(如GET、POST、PUT、DELETE等)来处理不同的API请求。
5. 在控制器类中,使用[Route]属性来定义API方法的路由。这将决定API方法可以通过哪个URL进行访问。
6. 在控制器类中,使用[HttpGet]、[HttpPost]等属性来定义API方法的HTTP动词。
7. 在控制器类中,实现API方法的具体逻辑。这可能包括从数据库中检索数据、处理请求参数等。
8. 在WinForms应用程序的入口点(例如Main函数)中,使用System.Web.Http.SelfHost命名空间来启动Web API服务器。
9. 在Web API服务器的启动代码中,使用HttpSelfHostConfiguration类来配置服务器设置,例如指定要监听的端口号、启用跨域访问等。
10. 在Web API服务器的启动代码中,使用HttpSelfHostServer类来创建并启动服务器。
11. 运行你的C# WinForms应用程序,并确保Web API服务器已经成功启动。
现在,你的C# WinForms应用程序中就有一个Web API服务器了,可以通过API方法来处理HTTP请求。你可以使用工具(例如Postman)来测试和调试API方法。请记住,这只是一个基本的示例,你可以根据自己的需求进行更多的定制化和功能扩展。
print("\tpython")
print("languages:\npython\nC\njacascript")
print("languages:\n\tpython\n\tC\n\tjacascript")
[/code]