博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
开源组件websocket-sharp中基于webapi的httpserver使用体验
阅读量:4639 次
发布时间:2019-06-09

本文共 9753 字,大约阅读时间需要 32 分钟。

一、背景

  因为需要做金蝶ERP的二次开发,金蝶ERP的开放性真是不错,但是二次开发金蝶一般使用引用BOS.dll的方式,这个dll对newtonsoft.json.dll这个库是强引用,必须要用4.0版本,而asp.net mvc的webapi client对newtonsoft.json.dll的最低版本是6.0.这样就不能用熟悉的webapi client开发了。金蝶ERP据说支持无dll引用方式,标准的webapi方式,但官方支持有限,网上的文档也有限且参考意义不大。所以最后把目光聚集在自建简单httpserver上,最好是用.net 4作为运行时。在此感谢“”作者的分享,了解到这个开源组件。

二、定制和修改

  • 1、修改“注入控制器到IOC容器”的方法适应现有项目的解决方案程序集划分
  • 2、修改“响应HttpPost请求”时方法参数解析和传递方式,增加了“FromBoby”自定义属性来标记参数是个数据传输对象。
  • 3、扩展了返回值类型,增加了HtmlResult和ImageResult等类型

代码:

       1)、修改“注入控制器到IOC容器”的方法

///         /// 注入控制器到IOC容器        ///         ///         public void InitController(ContainerBuilder builder)        {            Assembly asb = Assembly.Load("Business.Controller");            if (asb != null)            {                var typesToRegister = asb.GetTypes()                                      .Where(type => !string.IsNullOrEmpty(type.Namespace))                                      .Where(type => type.BaseType == typeof(ApiController) || type.BaseType.Name.Equals("K3ErpBaseController"));                if (typesToRegister.Count() > 0)                {                    foreach (var item1 in typesToRegister)                    {                        builder.RegisterType(item1).PropertiesAutowired();                        foreach (var item2 in item1.GetMethods())                        {                            IExceptionFilter _exceptionFilter = null;                            foreach (var item3 in item2.GetCustomAttributes(true))                            {                                Attribute temp = (Attribute)item3;                                Type type = temp.GetType().GetInterface(typeof(IExceptionFilter).Name);                                if (typeof(IExceptionFilter) == type)                                {                                    _exceptionFilter = item3 as IExceptionFilter;                                }                            }                            MAction mAction = new MAction()                            {                                RequestRawUrl = @"/" + item1.Name.Replace("Controller", "") + @"/" + item2.Name,                                Action = item2,                                TypeName = item1.GetType().Name,                                ControllerType = item1,                                ParameterInfo = item2.GetParameters(),                                ExceptionFilter = _exceptionFilter                            };                            dict.Add(mAction.RequestRawUrl, mAction);                        }                    }                }            }            container = builder.Build();        }

  2)、修改“响应HttpPost请求”时方法参数解析和传递方式,增加了“FromBoby”自定义属性;增加了HtmlResult和ImageResult等类型

///         /// 响应HttpPost请求        ///         ///         ///         private void Httpsv_OnPost(object sender, HttpRequestEventArgs e)        {            MAction requestAction = new MAction();            string content = string.Empty;            try            {                byte[] binaryData = new byte[e.Request.ContentLength64];                content = Encoding.UTF8.GetString(GetBinaryData(e, binaryData));                string action_name = string.Empty;                if (e.Request.RawUrl.Contains("?"))                {                    int index = e.Request.RawUrl.IndexOf("?");                    action_name = e.Request.RawUrl.Substring(0, index);                }                else                    action_name = e.Request.RawUrl;                if (dict.ContainsKey(action_name))                {                    requestAction = dict[action_name];                    object first_para_obj;                    object[] para_values_objs = new object[requestAction.ParameterInfo.Length];                    //没有参数,默认为空对象                    if (requestAction.ParameterInfo.Length == 0)                    {                        first_para_obj = new object();                    }                    else                    {                        int para_count = requestAction.ParameterInfo.Length;                        for (int i = 0; i < para_count; i++)                        {                            var para = requestAction.ParameterInfo[i];                            if (para.GetCustomAttributes(typeof(FromBodyAttribute), false).Any())                            {                                //反序列化Json对象成数据传输对象                                var dto_object = para.ParameterType;                                para_values_objs[i] = JsonConvert.DeserializeObject(content, dto_object);                            }                            else                            {                                //参数含有FromBodyAttribute的只能有一个,且必须是第一个                                int index = e.Request.RawUrl.IndexOf("?");                                if (e.Request.RawUrl.Contains("&"))                                {                                    bool existsFromBodyParameter = false;                                    foreach (var item in requestAction.ParameterInfo)                                    {                                        if (item.GetCustomAttributes(typeof(FromBodyAttribute), false).Any())                                        {                                            existsFromBodyParameter = true;                                            break;                                        }                                    }                                    string[] url_para = e.Request.RawUrl.Substring(index + 1).Split("&".ToArray(), StringSplitOptions.RemoveEmptyEntries);                                    if (existsFromBodyParameter)                                        para_values_objs[i] = url_para[i - 1].Replace(para.Name + "=", "");                                    else                                        para_values_objs[i] = url_para[i].Replace(para.Name + "=", "");                                }                                else                                {                                    para_values_objs[i] = e.Request.RawUrl.Substring(index + 1).Replace(para.Name + "=", "");                                }                            }                        }                    }                    var action = container.Resolve(requestAction.ControllerType);                    var action_result = requestAction.Action.Invoke(action, para_values_objs);                    if (action_result == null)                    {                        e.Response.StatusCode = 204;                    }                    else                    {                        e.Response.StatusCode = 200;                        if (requestAction.Action.ReturnType.Name.Equals("ApiActionResult"))                        {                            e.Response.ContentType = "application/json";                            byte[] buffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(action_result));                            e.Response.WriteContent(buffer);                        }                        if (requestAction.Action.ReturnType.Name.Equals("agvBackMessage"))                        {                            e.Response.ContentType = "application/json";                            byte[] buffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(action_result));                            e.Response.WriteContent(buffer);                        }                        else if (requestAction.Action.ReturnType.Name.Equals("HtmlResult"))                        {                            HtmlResult result = (HtmlResult)action_result;                            e.Response.ContentType = result.ContentType;                            byte[] buffer = result.Encoder.GetBytes(result.Content);                            e.Response.WriteContent(buffer);                        }                        else if (requestAction.Action.ReturnType.Name.Equals("ImageResult"))                        {                            ImageResult apiResult = (ImageResult)action_result;                            e.Response.ContentType = apiResult.ContentType;                            byte[] buffer = Convert.FromBase64String(apiResult.Base64Content.Split(",".ToArray(), StringSplitOptions.RemoveEmptyEntries).LastOrDefault());                            e.Response.WriteContent(buffer);                        }                        else                        {                            byte[] buffer = Encoding.UTF8.GetBytes(action_result.ToString());                            e.Response.WriteContent(buffer);                        }                    }                }                else                {                    e.Response.StatusCode = 404;                }            }            catch (Exception ex)            {                if (requestAction.ExceptionFilter == null)                {                    byte[] buffer = Encoding.UTF8.GetBytes(ex.Message + ex.StackTrace);                    e.Response.WriteContent(buffer);                    e.Response.StatusCode = 500;                }                else                {                    if (requestAction.ExceptionFilter != null)                    {                        if (ex.InnerException != null)                        {                            requestAction.ExceptionFilter.OnException(ex.InnerException, e);                        }                        else                        {                            requestAction.ExceptionFilter.OnException(ex, e);                        }                    }                }            }        }

三、体验概述

  • 1、稳,可用性很高,简单直接。
  • 2、使用之后对mvc的底层理解提高很多。
  • 3、对Autofac等IOC容器有了新的认识,项目里大量使用了属性注入方式来解除耦合。

四、一些截图

转载于:https://www.cnblogs.com/datacool/p/websocket-sharp.html

你可能感兴趣的文章
关于jedis2.4以上版本的连接池配置,及工具类
查看>>
记忆讲师石伟华微信公众号2017所有文章汇总(待更新)
查看>>
mechanize (1)
查看>>
FactoryBean
查看>>
Coolite动态加载CheckboxGroup,无法在后台中获取
查看>>
如何在我们项目中利用开源的图表(js chart)
查看>>
nfs服务器工作原理
查看>>
C3P0连接池工具类使用
查看>>
SVN常用命令备注
查看>>
孩子教育
查看>>
解决Cacti监控图像断断续续问题
查看>>
结构体的传参理解成员的存储方式
查看>>
python 进程与线程(理论部分)
查看>>
什么是API
查看>>
Java反射中method.isBridge() 桥接方法
查看>>
[shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
查看>>
强名称程序集(strong name assembly)——为程序集赋予强名称
查看>>
1028. List Sorting (25)
查看>>
BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划
查看>>
ubuntu 重启命令,ubuntu 重启网卡方法
查看>>