欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-16 08:14:12
优雅的在WinForm/WPF/控制台 中使用特性封装WebApi 说明 ` 在C/S端作为Server,建立HTTP请求,方便快捷。 ` 1.使用到的类库 ` Newtonsoft.dll ` 2.封装 HttpListener HttpApi类 特性类 ActionName 特性类 HttpMe ......

优雅的在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 start()
        {
            // 获取完全名称
            string classname = new stacktrace().getframe(1).getmethod().reflectedtype.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();

                        //参数
                        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;
        }

    }
帮助类 jsonhelp
    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在load事件最后一行中增加
    httpapi.start();
  • 4.2具体使用方法 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 交流!