zoukankan      html  css  js  c++  java
  • 优雅的在WinForm/WPF/控制台 中使用特性封装WebApi

    优雅的在WinForm/WPF/控制台 中使用特性封装WebApi

    说明

    在C/S端作为Server,建立HTTP请求,方便快捷。

    1.使用到的类库

    Newtonsoft.dll

    2.封装 HttpListener

    HttpApi类
        public class HttpApi
        {
    
            private static List<HttpListener> HttpListenerList = new List<HttpListener>();
    
            /// <summary>
            /// 初始化服务
            /// </summary>
            public static void InitService()
            {
    
                //获取程序集下面的所有的类
                Type[] types = System.Reflection.Assembly.GetExecutingAssembly().GetTypes();
                foreach (Type item_type in types)
                {
                    //定义是否有类的特性标识
                    bool IsHasFormApi = false;
                    //取类上的自定义特性
                    object[] objs = item_type.GetCustomAttributes(typeof(FromApi), true);
                    foreach (object obj in objs)
                    {
                        FromApi fromApi = obj as FromApi;
                        if (fromApi != null)
                        {
                            IsHasFormApi = true;
                            break;
                        }
                    }
                    if (IsHasFormApi)
                    {
                        // 获取完全名称
                        String className = item_type.FullName;
    
                        // 根据命名空间反射类的Type
                        Type type = Type.GetType(className);
                        object objInstance = type.Assembly.CreateInstance(className);
    
                        // 获取所有的方法
                        MethodInfo[] info = type.GetMethods();
    
                        // 遍历所有的方法
                        foreach (MethodInfo item in info)
                        {
    
                            // 获取Http请求方法
                            HttpMethod httpMethod = item.GetCustomAttribute<HttpMethod>();
                            // 获取Action
                            ActionName actionName = item.GetCustomAttribute<ActionName>();
    
                            // 判断有没有特性
                            if (httpMethod != null || actionName != null)
                            {
                                HttpListener listerner = new HttpListener();
                                listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问
                                string url = "http://127.0.0.1:8011";
                                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["httpserver"]))
                                {
                                    url = "http://" + ConfigurationManager.AppSettings["httpserver"];
                                }
                                listerner.Prefixes.Add(url + actionName.URL + "/");
    
                                //开启服务
                                if (!listerner.IsListening)
                                {
                                    listerner.Start();
                                    AsyncCallback ac = new AsyncCallback(GetContextAsyncCallback);
                                    CallbackObject callback = new CallbackObject() { Listerner = listerner, MethodItem = item, ClassInstance = objInstance, HttpMethod = httpMethod.method };
                                    listerner.BeginGetContext(ac, callback);
                                    HttpListenerList.Add(listerner);
                                }
                            }
    
                        }
                    }
                }
    
    
            }
    
            /// <summary>
            /// 收到监听请求回调
            /// </summary>
            /// <param name="ia"></param>
            private static void GetContextAsyncCallback(IAsyncResult ia)
            {
                CallbackObject state = ia.AsyncState as CallbackObject;
                if (ia.IsCompleted)
                {
                    HttpListenerContext ctx = state.Listerner.EndGetContext(ia);
    
                    var request = ctx.Request;
    
                    HttpListenerResponse response = ctx.Response;
    
    
                    try
                    {
    
                        //判断 请求 方式
                        if (request.HttpMethod.ToUpper() == state.HttpMethod.ToString().ToUpper() || Method.All.ToString().ToUpper() == state.HttpMethod.ToString().ToUpper())
                        {
                            string rawData;
    
                            using (var reader = new StreamReader(request.InputStream, request.ContentEncoding))
                            {
                                rawData = reader.ReadToEnd();
                            }
    
    
                            //获取方法参数列表
    
                            ParameterInfo[] parameterInfos = state.MethodItem.GetParameters();
    
                            //参数
                            // List<object> paramters = new List<object>();
                            object[] paramters = new object[parameterInfos.Length];
    
                            for (int i = 0; i < parameterInfos.Length; i++)
                            {
                                ParameterInfo item = parameterInfos[i];
                                if (item.ParameterType == typeof(string) || item.ParameterType == typeof(int) || item.ParameterType == typeof(bool))
                                {
                                    paramters[i] = JsonHelper.GetJsonValue(rawData, item.Name);
                                }
                                else
                                {
                                    Type t = item.ParameterType;
                                    paramters[i] = JsonConvert.DeserializeObject(rawData, t);
                                }
                            }
    
    
                            object resobj = state.MethodItem.Invoke(state.ClassInstance, paramters);
                            if (typeof(string) == resobj.GetType())
                            {
                                ResponseWrite(response, resobj.ToString());
                            }
                            else
                            {
                                ResponseWrite(response, JsonConvert.SerializeObject(resobj));
                            }
                        }
                        else
                        {
                            ResponseWrite(response, $"不支持{request.HttpMethod.ToUpper()}方法请求!");
                        }
                    }
                    catch (Exception ex)
                    {
                        ResponseWrite(response, $"服务出现异常,异常信息:{ex.Message}");
                    }
                }
    
                //重新监听  不写的话只能调用一次 
                AsyncCallback ac = new AsyncCallback(GetContextAsyncCallback);
                state.Listerner.BeginGetContext(ac, state);
            }
    
            /// <summary>
            /// 回写响应
            /// </summary>
            /// <param name="response"></param>
            /// <param name="Content"></param>
            private static void ResponseWrite(HttpListenerResponse response, string Content)
            {
                //使用Writer输出http响应代码
                using (System.IO.StreamWriter writer = new System.IO.StreamWriter(response.OutputStream, new UTF8Encoding()))
                {
                    response.ContentType = "application/json; charset=utf-8";
                    writer.WriteLine(Content);
                    writer.Close();
                    response.Close();
                }
            }
        }
    
    
    
        public enum Method
        {
            All, Post, Get
        }
    
        public class CallbackObject
        {
            /// <summary>
            /// 监听
            /// </summary>
            public HttpListener Listerner { get; set; }
    
            /// <summary>
            /// 方法
            /// </summary>
            public MethodInfo MethodItem { get; set; }
    
            /// <summary>
            /// 调用者 对象
            /// </summary>
            public object ClassInstance { get; set; }
    
            /// <summary>
            /// 调用方式 Get Post
            /// </summary>
            public Method HttpMethod { get; set; }
        }
    
    特性类 ActionName
        [AttributeUsage(AttributeTargets.Method)]
        class ActionName : Attribute
        {
            public string URL { get; set; }
            public ActionName()
            {
    
            }
            public ActionName(string url)
            {
                this.URL = url;
            }
        }
    
    特性类 HttpMethod
        [AttributeUsage(AttributeTargets.Method)]
        public class HttpMethod : Attribute
        {
            public Method method { get; set; }
            public HttpMethod()
            {
                this.method = Method.All;
            }
    
            public HttpMethod(Method _method)
            {
                this.method = _method;
            }
    
        }
    
    特性类 FromApi
        [AttributeUsage(AttributeTargets.Class)]
        public class FromApi : Attribute
        {
            //窗体里的具体方法忽略
        }
    
    帮助类 JsonHelper
        public static class JsonHelper
        {
            public static string GetJsonValue(string json, string key)
            {
                string value = "";
                if (string.IsNullOrEmpty(json)) { return ""; }
                JObject jo = (JObject)JsonConvert.DeserializeObject(json);
                if (jo.ContainsKey(key))
                {
                    if (jo[key] != null)
                    {
                        value = jo[key].ToString();
                    }
                }
                return value;
            }
            public static List<string> GetJsonList(string json, string key)
            {
                List<string> value = new List<string>();
                if (string.IsNullOrEmpty(json)) { return new List<string>(); }
                JObject jo = (JObject)JsonConvert.DeserializeObject(json);
                if (jo.ContainsKey(key))
                {
                    if (jo[key] != null)
                    {
                        foreach (var item in jo[key])
                        {
                            value.Add(item.ToString());
                        }
                    }
                }
                return value;
            }
        }
    

    3.在Web.config中增加

      <appSettings>
        <add key="httpserver" value="127.0.0.1:8022"/>
      </appSettings>
    

    4.使用方法

    • 4.1在窗体类上增加 [FromApi] 特性
        [FromApi]
        public partial class ScoketForm : Form
        {
            
        }
    
    • 4.2Program.cs 中增加 这种初始化方式会对程序集中所有带有 [FromApi] 特性的类进行初始化
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        //服务初始化
        HttpApi.InitService();  //这里是增加初始化的代码
        Application.Run(new SocketTest.gg.ScoketForm());
    
    • 4.3具体使用方法 HttpMethod 后面可以不写,不写的话代表 支持两种请求方式 POST,GET 需要注意命名空间的导入
            /// <summary>
            /// 方法说明
            /// </summary>
            /// <returns></returns>
            [HttpMethod(Method.Post), ActionName("/api/index")]
            public HttpResult Index(List<string> Ids)
            {
    
                HttpResult httpResult = new HttpResult();
    
                //具体方法内容
                return httpResult;
            }
    
    如有疑问欢迎加入QQ群:765907694 交流!
  • 相关阅读:
    ios 读取通讯录
    隐藏多余的分割线
    Cell高亮时设置cell内容
    iOS录音
    iOS发送信息功能(生成信息内容)
    iOS颜色选择器
    iOS缓存
    二维码扫描
    梵讯笔记
    微信开发后台库
  • 原文地址:https://www.cnblogs.com/Yann123/p/11365669.html
Copyright © 2011-2022 走看看