zoukankan      html  css  js  c++  java
  • 开源组件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容器有了新的认识,项目里大量使用了属性注入方式来解除耦合。

    四、一些截图

  • 相关阅读:
    第五课:数字门构造
    出一道题 : 证明 牛顿迭代法
    网友 水登江河 说
    出现 杨辉三角 的 一些 场合
    泰勒级数 无敌 逼近法
    出一道题 : 证明 ln | sec x + tan x | =
    从 角动量守恒 推导出 椭圆轨道
    三角函数 版 的 霍奇猜想
    傅里叶级数 和 高次多项式函数
    实际上, 物空必能 先生 的 一些 观点 可能 是 正确 的
  • 原文地址:https://www.cnblogs.com/datacool/p/websocket-sharp.html
Copyright © 2011-2022 走看看