『7x24小时有问必答』
C# WinForm 程序中实现一个简易的 HTTP 服务器,能够处理 JSON 格式的 GET 和 POST 请求,这是一个很实用的需求,尤其适合做本地调试或轻量级服务。

实现思路

我会基于.NET自带的HttpListener类来实现这个 HTTP 服务器,它可以让 WinForm 程序监听指定端口并处理 HTTP 请求。核心步骤包括:
1、初始化HttpListener并配置监听地址
2、异步监听并处理客户端请求
3、区分 GET/POST 请求类型
4、解析 / 响应 JSON 格式数据
5、在 WinForm 界面中控制服务器的启动和停止

完整代码实现

以下是一个开箱即用的 WinForm 程序代码,包含 UI 交互和完整的 HTTP 服务逻辑:

1. 首先是 Form1 的设计(Form1.Designer.cs 核心部分)

using  System;using  System.IO;using  System.Net;using  System.Text;using  System.Threading;using  System.Windows.Forms;// 仅保留Newtonsoft.Json引用using  Newtonsoft.Json;  namespace  WinFormHttpServer{       public  partial  class  Form1  :  Form      {             private  HttpListener _httpListener;             private  Thread _listenerThread;             private  bool  _isListening;             // 测试用的实体类             public  class  UserInfo            {                   public  int  Id {  get;  set; }                   public  string  Name {  get;  set; }                   public  string  Email {  get;  set; }            }             public  Form1()            {                  InitializeComponent();            }             #region  按钮事件(无修改)             private  void  btnStart_Click(object  sender, EventArgs e)            {                   try                  {                         int  port;                         if  (!int.TryParse(txtPort.Text.Trim(),  out  port) || port <  1  || port >  65535)                        {                              MessageBox.Show("请输入有效的端口号(1-65535)",  "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);                               return;                        }                        _httpListener =  new  HttpListener();                        _httpListener.Prefixes.Add($"http://*:{port}/");                        _httpListener.Start();                        _isListening =  true;                        _listenerThread =  new  Thread(ListenForRequests);                        _listenerThread.IsBackground =  true;                        _listenerThread.Start();                        btnStart.Enabled =  false;                        btnStop.Enabled =  true;                        txtPort.Enabled =  false;                        Log($"服务器已启动,监听地址:http://localhost:{port}/");                  }                   catch  (Exception ex)                  {                        Log($"启动失败:{ex.Message}");                        MessageBox.Show($"启动失败:{ex.Message}",  "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);                  }            }             private  void  btnStop_Click(object  sender, EventArgs e)            {                  StopServer();            }             private  void  Form1_FormClosing(object  sender, FormClosingEventArgs e)            {                  StopServer();            }             #endregion             #region  核心服务逻辑(无修改)             private  void  StopServer()            {                   if  (_isListening)                  {                        _isListening =  false;                        _httpListener?.Stop();                        _listenerThread?.Join(1000);                        btnStart.Enabled =  true;                        btnStop.Enabled =  false;                        txtPort.Enabled =  true;                        Log("服务器已停止");                  }            }             private  void  ListenForRequests()            {                   while  (_isListening)                  {                         try                        {                               var  context = _httpListener.GetContext();                               new  Thread(() => ProcessRequest(context)).Start();                        }                         catch  (HttpListenerException)                        {                               break;                        }                         catch  (Exception ex)                        {                              Log($"请求处理异常:{ex.Message}");                        }                  }            }             private  void  ProcessRequest(HttpListenerContext context)            {                   var  request = context.Request;                   var  response = context.Response;                   try                  {                        Log($"收到请求 - 方法:{request.HttpMethod},路径:{request.Url.PathAndQuery}");                         string  responseString =  "";                         if  (request.HttpMethod ==  "GET")                        {                               var  user =  new  UserInfo                              {                                    Id =  1,                                    Name =  "测试用户",                                    Email =  "test@example.com"                              };                               // 调用修正后的序列化方法                              responseString = SerializeToJson(user);                        }                         else  if  (request.HttpMethod ==  "POST")                        {                               string  requestJson = ReadRequestData(request);                              Log($"POST请求内容:{requestJson}");                               var  user = DeserializeFromJson<userinfo>(requestJson);                               if  (user !=  null)                              {                                    user.Name =  $"处理后的{user.Name}";                                    responseString = SerializeToJson(new  { Success =  true, Message =  "POST请求处理成功", Data = user });                              }                               else                              {                                    responseString = SerializeToJson(new  { Success =  false, Message =  "JSON格式错误"  });                              }                        }                         else                        {                              responseString = SerializeToJson(new  { Success =  false, Message =  $"不支持的请求方法:{request.HttpMethod}"  });                              response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;                        }                         // 编码控制在这里(UTF8),而非序列化配置中                        response.ContentType =  "application/json; charset=utf-8";                        response.ContentEncoding = Encoding.UTF8;                         byte[] buffer = Encoding.UTF8.GetBytes(responseString);                        response.ContentLength64 = buffer.Length;                         using  (var  output = response.OutputStream)                        {                              output.Write(buffer,  0, buffer.Length);                        }                        Log($"响应发送完成:{responseString}");                  }                   catch  (Exception ex)                  {                        Log($"处理请求异常:{ex.Message}");                         string  errorJson = SerializeToJson(new  { Success =  false, Message = ex.Message });                         byte[] errorBuffer = Encoding.UTF8.GetBytes(errorJson);                        response.StatusCode = (int)HttpStatusCode.InternalServerError;                        response.ContentType =  "application/json; charset=utf-8";                        response.ContentLength64 = errorBuffer.Length;                         using  (var  output = response.OutputStream)                        {                              output.Write(errorBuffer,  0, errorBuffer.Length);                        }                  }                   finally                  {                        response.Close();                  }            }             #endregion             #region  辅助方法(修复Encoding错误)             ///  <summary>             ///  读取请求体数据             ///  </summary>             private  string  ReadRequestData(HttpListenerRequest request)            {                   using  (var  reader =  new  StreamReader(request.InputStream, request.ContentEncoding))                  {                         return  reader.ReadToEnd();                  }            }             ///  <summary>             ///  修复:移除了错误的Encoding配置,保留其他有用配置             ///  </summary>             private  string  SerializeToJson(object  obj)            {                   var  settings =  new  JsonSerializerSettings                  {                        Formatting = Formatting.Indented,  // 格式化输出JSON                        NullValueHandling = NullValueHandling.Ignore,  // 忽略空值属性                         // 移除了错误的 Encoding = Encoding.UTF8 配置                        StringEscapeHandling = StringEscapeHandling.EscapeNonAscii  // 可选:转义非ASCII字符(如中文)                  };                   return  JsonConvert.SerializeObject(obj, settings);            }             ///  <summary>             ///  反序列化方法(无错误)             ///  </summary>             private  T  DeserializeFromJson<T>(string  json)            {                   try                  {                         var  settings =  new  JsonSerializerSettings                        {                              MissingMemberHandling = MissingMemberHandling.Ignore  // 忽略JSON中不存在的属性                        };                         return  JsonConvert.DeserializeObject<t>(json, settings);                  }                   catch  (JsonException ex)                  {                        Log($"JSON反序列化失败:{ex.Message}");                         return  default(T);                  }            }             ///  <summary>             ///  日志输出             ///  </summary>             private  void  Log(string  message)            {                   if  (txtLog.InvokeRequired)                  {                        txtLog.Invoke(new  Action<string>(Log), message);                  }                   else                  {                        txtLog.AppendText($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}]  {message}{Environment.NewLine}");                        txtLog.ScrollToCaret();                  }            }             #endregion      }}
1.png
APIPost软件测试:
2.png

关键代码解释

1、HttpListener
:核心类,用于监听 HTTP 请求,支持多前缀、多请求处理
2、多线程处理
:监听线程和请求处理线程分离,避免阻塞 UI 线程
3、JSON 序列化 / 反序列化
:使用JavaScriptSerializer处理 JSON 数据(也可以替换为 Newtonsoft.Json,更推荐)
4、跨线程 UI 更新
:通过Control.Invoke实现日志的跨线程输出,避免 WinForm 跨线程访问异常
5、异常处理
:完善的异常捕获和错误响应,保证服务器稳定运行

总结

1、该 WinForm 服务器基于HttpListener实现,能够稳定处理 JSON 格式的 GET/POST 请求,核心是异步监听 + 多线程处理请求,避免阻塞 UI。
2、关键要点:需要管理员权限运行、正确处理跨线程 UI 更新、严格遵循 HTTP 响应规范(设置 Content-Type、关闭响应流)。
</t></userinfo>

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码