一、背景

  因为需要做金蝶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作为运行时。在此感谢“C#基于websocket-sharp实现简易httpserver(封装)”作者的分享,了解到这个开源组件。

二、定制和修改

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

代码:

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

 /// <summary>/// 注入控制器到IOC容器/// </summary>/// <param name="builder"></param>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等类型

  /// <summary>/// 响应HttpPost请求/// </summary>/// <param name="sender"></param>/// <param name="e"></param>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);}elseaction_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 + "=", "");elsepara_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

开源组件websocket-sharp中基于webapi的httpserver使用体验相关推荐

  1. 开源组件 Ehcache中被曝严重漏洞,影响多款Jira产品

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士 Atlassian 公司督促企业客户修复其 Jira Data Center 和 Jira Service Management Data ...

  2. Winform中使用EasyPlayer-RTSP-Win开源组件实现播放RTSP视频流

    场景 开源RTMP组件EasyPusher-Android+EasyDarwin实现APP推流给RTSP流媒体服务器: 开源RTMP组件EasyPusher-Android+EasyDarwin实现A ...

  3. Java 代码基于开源组件生成带头像的二维码

    二维码在我们目前的生活工作中,随处可见,日常开发中难免会遇到需要生成二维码的场景,网上也有很多开源的平台可以使用,不过这里我们可以通过几个开源组件,自己来实现一下. 在动手之前我们先思考一下需要进行的 ...

  4. Java 代码基于开源组件生成带头像的二维码,推荐收藏

    二维码在我们目前的生活工作中,随处可见,日常开发中难免会遇到需要生成二维码的场景,网上也有很多开源的平台可以使用,不过这里我们可以通过几个开源组件,自己来实现一下. 在动手之前我们先思考一下需要进行的 ...

  5. vue tree组件_基于 Vue2.0 和 HeyUI 组件库的中后端系统 HeyUI Admin

    介绍 heyui-admin 是一个成熟的企业应用解决方案,基于 vue2.0 和 heyui 组件库的中后端系统. 功能 - Js - common / 通用 - ajax / 封装axios - ...

  6. 后端常用开源组件合集(持续更新中)

    1. 常用库 awesome - golang开源库集合 2. 编码规范 cppguide - C++编码规范 CodeReviewComments - go code review建议 3. 敏捷开 ...

  7. Uncode系列开源组件简介

    概述 Uncode 是基于Java 语言的一系列企业级开源组件,作者冶卫军 (开源作者花费大量时间维护开源项目,期望正确使用).主要包括:移动后端开发框架Uncode-BaaS ,通用数据库访问组件U ...

  8. 开源组件ExcelReport 1.5.2 使用手册

    ExcelReport是一款基于NPOI开发的报表引擎组件.它基于关注点分离的理念,将数据与样式.格式分离.让模板承载样式.格式等NPOI不怎么擅长且实现繁琐的信息,结合NPOI对数据的处理的优点将E ...

  9. 开源组件是什么意思_一文读懂常用开源许可证

    社区时常为流行产品中有争议的开源许可证而感到震惊,这引起各方关注,纷纷争论何为真正的开源许可证.去年,Apache 基金会(Apache Foundation)禁止使用 Facebook React ...

最新文章

  1. 用 Redis 处理 jsonwebtoken 生成的 Token
  2. 使用TensorFlow训练WDL模型性能问题定位与调优
  3. iOS核心动画之CALayer-隐式动画
  4. 事业单位计算机初级考试科目一模拟试题,广东教师资格考试之科目一模拟题
  5. 【2017年第3期】面向共享的政府大数据质量标准化问题研究
  6. app抢购脚本如何编写_如何用1个记事本文件征服全世界?——cmd批处理脚本编写...
  7. NLP --- 条件随机场CRF背景
  8. 系统集成项目管理工程师 案例题【2021上】 总结
  9. PYTHON对接验证码短信接口DEMO示例
  10. JavaScript 编程精解 中文第三版 五、高阶函数
  11. PHP中的定界符 echo
  12. ivms虚拟服务器,ivms监控服务器地址
  13. 程序员常用刷题网站分享
  14. Flash和XML实现电子地图查询及定位功能
  15. OSG 中 常用的 Uniforms
  16. Linux下使用 shell 脚本实现ftp文件下载
  17. 【数据库02】==== 表的增删改查(基础)
  18. React Native 炫酷的动画库 实现任何AE动画 lottie-react-native
  19. justify-content具体属性值
  20. 谷歌浏览器播放视频没有声音解决

热门文章

  1. zeroclipboard 粘贴板的应用示例, 兼容 Chrome、IE等多浏览器
  2. libgstreamer-1.0.so.0: cannot open shared object file: No such file or directory
  3. Python 标准库之 json
  4. django自带的分页功能
  5. Kali2021.2 VMware最新版安装步骤
  6. 数据库里存json数据
  7. tf.placeholder函数说明
  8. GOF23设计模式(创建型模式)建造者模式
  9. AI 芯片的分类及技术
  10. HarmonyOS技术特性