C#程序模拟网站服务器(如PHP、ASP等任意类型)接收GET、POST请求信息,实现REST_API接口服务

1、依赖环境

Newtonsoft JSON库,严重依赖
LogHelper 自写的日志记录库 只记录调试信息 可替换或不用

2、类的实现代码

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;


public class RestApiServer
{
    /// <summary>
    /// HTTP监听服务
    /// </summary>
    private HttpListener server = new HttpListener();
    /// <summary>
    /// 声明数据接收委托
    /// </summary>
    /// <param name="method"></param>
    /// <param name="data"></param>
    public delegate void delegate_receive_data(string method, Dictionary<string, object> data);
    /// <summary>
    /// 声明事件
    /// </summary>
    public event delegate_receive_data receive_data;


    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="url">监听URL地址</param>
    public RestApiServer(string url)
    {
        server.Prefixes.Add(url); //添加服务前缀
        server.Start(); //开启服务
        server.BeginGetContext(new AsyncCallback(GetContextCallBack), server); //接收数据 异步方式
    }

    /// <summary>
    /// 接收数据
    /// </summary>
    /// <param name="ar"></param>
    private void GetContextCallBack(IAsyncResult ar)
    {
        try
        {
            server = ar.AsyncState as HttpListener;
            HttpListenerContext context = server.EndGetContext(ar);
            server.BeginGetContext(new AsyncCallback(GetContextCallBack), server);

            Dictionary<string, object> nc_get = new Dictionary<string, object>();
            Dictionary<string, object> nc_post = new Dictionary<string, object>();



            context.Response.AppendHeader("Access-Control-Allow-Origin", "*");//后台跨域请求,通常设置为配置文件
            context.Response.AppendHeader("server", "SharpServer 1.0 by lzl640");//后台跨域请求,通常设置为配置文件
            context.Response.StatusCode = 200;//设置返回给客服端http状态代码

            JToken j_get = null; //GET传值
            JToken j_post = null; //POST传值


            //处理请求
            switch (context.Request.HttpMethod)
            {
                case "POST":
                    HttpListenerPostParaHelper httppost = new HttpListenerPostParaHelper(context);//获取Post请求中的参数和值帮助类  
                    List<HttpListenerPostValue> lst = httppost.GetHttpListenerPostValue();//获取Post过来的参数和数据  

                    foreach (var item in lst)
                    {
                        string key = item.name;
                        string value = Encoding.UTF8.GetString(item.datas).Replace("\r\n", "");
                        nc_post.Add(key, value);
                    }
                    j_post = JToken.FromObject(nc_post);
                    break;
                case "GET":
                    NameValueCollection nvc = HttpUtility.ParseQueryString(context.Request.Url.Query, Encoding.GetEncoding("utf-8"));
                    var items = nvc.AllKeys.SelectMany(nvc.GetValues, (k, v) => new { key = k, value = v });
                    foreach (var item in items)
                    {
                        nc_get.Add(item.key, item.value);
                    }   
                    j_get = JToken.FromObject(nc_get);
                    break;
                default:
                    break;
            }
            //回答内容
            object obj = new
            {
                code = 0,
                message = "ok",
                method = context.Request.HttpMethod,
                get_value = j_get,
                post_value = j_post,
            };

            JObject jo = JObject.FromObject(obj);

            string responseString = jo.ToString();

            byte[] buffer_utf8 = Encoding.GetEncoding("utf-8").GetBytes(responseString);
            Stream output = context.Response.OutputStream;
            //context.Response.KeepAlive = false;
            context.Response.ContentType = "application/json;charset=utf-8";
            output.Write(buffer_utf8, 0, buffer_utf8.Length);
            output.Close();
            //其它处理code

            switch (context.Request.HttpMethod)
            {
                case "GET":
                    if (j_get != null)
                    {
                        receive_data("GET", j_get.ToObject<Dictionary<string, object>>());
                    }
                    else
                    {
                       // receive_data("GET", null);
                    }

                    break;
                case "POST":
                    if (j_post != null)
                    {
                        receive_data("POST", j_post.ToObject<Dictionary<string, object>>());
                    }
                    else
                    {
                       // receive_data("POST", null);
                    }

                    break;
                default:
                    break;
            }


        }
        catch (Exception ex)
        {
            LogHelper.LogApi.WriteLog($@"解码错误:{ex.Message}");
            // Debug.Print($@"解码错误:{ex.Message}");
        }

    }

    /// <summary>  
    /// HttpListenner监听Post请求参数值实体  
    /// </summary>  
    private class HttpListenerPostValue
    {
        /// <summary>  
        /// 0=> 参数  
        /// 1=> 文件  
        /// </summary>  
        public int type = 0;
        public string name;
        public byte[] datas;
    }

    /// <summary>  
    /// 获取Post请求中的参数和值帮助类  
    /// </summary>  
    private class HttpListenerPostParaHelper
    {
        private HttpListenerContext request;

        public HttpListenerPostParaHelper(HttpListenerContext request)
        {
            this.request = request;
        }

        /// <summary>
        /// 比较字节数组
        /// </summary>
        /// <param name="source"></param>
        /// <param name="comparison"></param>
        /// <returns></returns>
        private bool CompareBytes(byte[] source, byte[] comparison)
        {
            try
            {
                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;
            }
        }
        /// <summary>
        /// 流转字节
        /// </summary>
        /// <param name="SourceStream"></param>
        /// <returns></returns>
        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()
        {
            try
            {
                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;
                        }
                    }
                }
                else if (request.Request.ContentType.Contains("application/x-www-form-urlencoded")) //QueryString: name_1=value_1&name_2=value_2
                {
                    StreamReader reader = new StreamReader(request.Request.InputStream);
                    string msg = reader.ReadToEnd();//读取传过来的信息
                    NameValueCollection nc_get = HttpUtility.ParseQueryString(msg, Encoding.GetEncoding("utf-8"));
                    for (int i = 0; i < nc_get.Count; i++)
                    {
                        HttpListenerPostValue data = new HttpListenerPostValue();
                        data.name = nc_get.GetKey(i);
                        data.datas = Encoding.UTF8.GetBytes(nc_get.Get(i));
                        HttpListenerPostValueList.Add(data);
                    }

                }
                else if (request.Request.ContentType.Contains("application/json")) //JSON格式字符串 {"name_1":"value_1","name_2":"value_2"}
                {
                    StreamReader reader = new StreamReader(request.Request.InputStream);
                    string msg = reader.ReadToEnd();//读取传过来的信息

                    Dictionary<string, object> dic = JToken.Parse(msg).ToObject<Dictionary<string, object>>();
                    foreach (var item in dic)
                    {
                        HttpListenerPostValue data = new HttpListenerPostValue();
                        data.name = item.Key.ToString();
                        data.datas = Encoding.UTF8.GetBytes(item.Value.ToString());
                        HttpListenerPostValueList.Add(data);
                    }

                }
                else if (request.Request.ContentType.Contains("text/plain")) //原始文本 value_1
                {
                    StreamReader reader = new StreamReader(request.Request.InputStream);
                    string msg = reader.ReadToEnd();//读取传过来的信息
                    HttpListenerPostValue data = new HttpListenerPostValue();
                    data.name = "data";
                    data.datas = Encoding.UTF8.GetBytes(msg);
                    HttpListenerPostValueList.Add(data);
                }

                return HttpListenerPostValueList;
            }
            catch (Exception ex)
            {
                LogHelper.LogApi.WriteLog($@"POST接收异常:{ex.Message}");
                return null;
            }
        }
    }
}


3、简单调用

public  RestApiServer rest_server;

	rest_server = new RestApiServer("http://192.168.1.2:8010/server.php/");
	//这个字符串前缀可任意写 只要 / 结尾就行,可以冒充 php、jsp、asp、cgi .......
	rest_server.receive_data += Rest_server_receive_data;
//关联数据接收事件


4、数据接收

public static void Rest_server_receive_data(string method, Dictionary<string, object> data)
    {
        Show_msg($@"API服务收到数据
方法:{method}
内容:
{JToken.FromObject(data)}
");
        //解码数据,配置写入数据库,如有必要、重启程序,重读配置信息
        if (data.Keys.Contains("a"))
        {
            MessageBox.Show("参数a接收到的信息"+ data["a"].ToString());
        }


    }

5、运行测试

浏览器 GET请求:
在这里插入图片描述
POST API 发送POST请求

在这里插入图片描述
POST API 发送POST JSON请求

在这里插入图片描述

程序界面响应:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzl640

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值