开源组件websocket-sharp中基于webapi的httpserver使用体验
一、背景
因为需要做金蝶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);
}
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容器有了新的认识,项目里大量使用了属性注入方式来解除耦合。
四、一些截图


开源组件websocket-sharp中基于webapi的httpserver使用体验的更多相关文章
- itest 开源测试管理项目中封装的下拉列表小组件:实现下拉列表使用者前后端0行代码
导读: 主要从4个方面来阐述,1:背景:2:思路:3:代码实现:4:使用 一:封装背景 像easy ui 之类的纯前端组件,也有下拉列表组件,但是使用的时候,每个下拉列表,要配一个URL ...
- 开源组件ExcelReport 1.5.2 使用手册
ExcelReport是一款基于NPOI开发的报表引擎组件.它基于关注点分离的理念,将数据与样式.格式分离.让模板承载样式.格式等NPOI不怎么擅长且实现繁琐的信息,结合NPOI对数据的处理的优点将E ...
- .net 开源组件
文章转自:http://www.cnblogs.com/asxinyu/p/dotnet_opensource_project_3.html 在前2篇文章这些.NET开源项目你知道吗?让.NET开 ...
- Android自定义控件 开源组件SlidingMenu的项目集成
在实际项目开发中,定制一个菜单,能让用户得到更好的用户体验,诚然菜单的样式各种各样,但是有一种菜单——滑动菜单,是被众多应用广泛使用的.关于这种滑动菜单的实现,我在前面的博文中也介绍了如何自定义去实现 ...
- 如何在WebSocket类中访问Session
我最近正在做一个基于websocket的webQQ,最后代码会开源带github上,所以过程中我就不贴所有的代码啦~就贴问题的关键. 我在WebSocket里发消息的时候需要用到session,因为在 ...
- BeetleX高性能通讯开源组件
net core高性能通讯开源组件BeetleX https://www.cnblogs.com/smark/p/9617682.html BeetleX beetleX是基于dotnet core实 ...
- 微信开源组件WCDB漫谈及Demo
代码地址如下:http://www.demodashi.com/demo/12422.html 前言 移动端的数据库选型一直是一个难题,直到前段时间看到了WeMobileDev(微信前端团队)放出了第 ...
- 饿了吗开源组件库Element模拟购物车系统
传统的用html+jquery来实现购物车系统要非常的复杂,但是购物车系统完全是一个数据驱动的系统,因此采用诸如Vue.js.angular.js这些框架要简单的多.饿了吗开源的组件库Element是 ...
- 如何利用阿里视频云开源组件,快速自定义你的H5播放器?
摘要: Aliplayer希望提供一种方便.简单.灵活的机制,让客户能够扩展播放器的功能,并且Aliplayer提供一些组件的基本实现,用户可以基于这些开源的组件实现个性化功能,比如自定义UI和自己A ...
随机推荐
- Clickhouse单机部署以及从mysql增量同步数据
背景: 随着数据量的上升,OLAP一直是被讨论的话题,虽然druid,kylin能够解决OLAP问题,但是druid,kylin也是需要和hadoop全家桶一起用的,异常的笨重,再说我也搞不定,那只能 ...
- sitecore 如何创建一个渠道分类
您可以通过渠道跟踪联系人与您的品牌的所有互动.您可以将渠道与广告系列活动相关联,以便跟踪联系人与您的品牌互动的方式.通过比较各个渠道的目标转化率,您可以了解哪些渠道可以带来更好的联系参与度.您可以在体 ...
- 超详细Pycharm部署项目视频教程
在实际的工作中,不管你是开发.测试还是运维人员,都应该掌握的一项技能就是部署项目,简单说就是把项目放到服务器中,使其正常运行.今天猪哥就以咱们的微信机器人项目为例子,带大家来部署一下项目.本文将会详细 ...
- 进程间通信的信道与控制(io机制)
进程间通信 = 信道 + 控制(状态) + io 信道: 1.流式信道: 2.队列信道: 3.共享内存信道: 控制机制: 数据就绪状态的通知与数据获取机制. 1.信号: 2.循环: 3.io机制
- Docker入门学习及其安装
1.Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源.Docker可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的Linux机器 ...
- RFC函数的初步使用-同步
1.由于没有外围系统,采用不同SAP不同client之间进行测试. 首先在A-client搭建需要被调用的RFC函数.在A-client里运行SE37创建函数 在属性页签选择“远程启用的模块” 设定i ...
- Java问题记录——OutOfMemoryError
Java问题记录——OutOfMemoryError 摘要:本文主要分析了OutOfMemoryError的产生原因. 没有分页导致占用大量内存 查看进程 使用 jps 命令查看当前运行的Java进程 ...
- SQLAlchemy--基本增删改查
目录 简介 安装 组成部分 简单使用 执行原生sql(不常用) orm使用(重点) 常用数据类型 Column常用参数 常用操作(CURD) 创建映射类的实例 创建会话Session 增加add()/ ...
- foreachRDD
需求: 将统计结果写入到MySQL create table wordcount( word varchar(50) default null, wordcount int(10) default n ...
- Django ajax 简单介绍
AJAX Asynchronous Javascript And XML是 "异步Javascript和XML".即使用 Javascript 语言与服务器进行异步交互,传输的数据 ...