• 硬件管理平台 - 公共项目搭建(Nancy部分)


    项目变更

    之前使用的是Nancy库进行项目搭建的,使用的Nuget版本及其他引用如下

    
    <packages>
    	<package id="Microsoft.AspNet.WebApi.Client" version="5.1.1" targetFramework="net451" />
    	<package id="Microsoft.AspNet.WebApi.Core" version="5.1.1" targetFramework="net451" />
    	<package id="Microsoft.AspNet.WebApi.Owin" version="5.1.1" targetFramework="net451" />
    	<package id="Microsoft.Owin" version="2.1.0" targetFramework="net451" />
    	<package id="Microsoft.Owin.FileSystems" version="2.1.0" targetFramework="net451" />
    	<package id="Microsoft.Owin.Host.HttpListener" version="2.1.0" targetFramework="net451" />
    	<package id="Microsoft.Owin.Hosting" version="2.1.0" targetFramework="net451" />
    	<package id="Microsoft.Owin.StaticFiles" version="2.1.0" targetFramework="net451" />
    	<package id="Nancy" version="0.22.2" targetFramework="net451" />
    	<package id="Nancy.Owin" version="0.22.2" targetFramework="net451" />
    	<package id="Nancy.Viewengines.Razor" version="0.22.2" targetFramework="net451" />
    	<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net451" />
    	<package id="Owin" version="1.0" targetFramework="net451" />
    	<package id="System.Web.Razor.Unofficial" version="2.0.2" targetFramework="net451" />
    	<package id="Topshelf" version="3.1.3" targetFramework="net451" />
    packages>
    

    昨天在搭建时感觉太多与臃肿,原因如下:

    1. 由于依托的为windows服务,且有独立配置程序,因此没有设计页面。

    2. 因之前版本多余久远,Nancy.Viewengines.Razor升级到2.2.0后会引入大量依赖,而不用前台页面也就不需要这个包了,与之类似的还有其他类似包体。

    3. 在优化时发现,可以不适用Nancy,而只是使用微软自带的WebApi依然可以完成。

    4. 之前版本太老,因此决定优化项目。

    WebApi平台搭建

    与之前一致,创建类库项目HardwareGatewayApi

    使用NuGet添加依赖,依次添加Microsoft.AspNet.WebApi.OwinSelfHostMicrosoft.Owin.Host.HttpListenerMicrosoft.Owin.HostingMicrosoft.AspNet.WebApiNewtonsoft.Json。packages.config如下:

    
    <packages>
      <package id="Microsoft.AspNet.WebApi" version="5.2.9" targetFramework="net462" />
      <package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net462" />
      <package id="Microsoft.AspNet.WebApi.Core" version="5.2.9" targetFramework="net462" />
      <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.9" targetFramework="net462" />
      <package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.9" targetFramework="net462" />
      <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.9" targetFramework="net462" />
      <package id="Microsoft.Owin" version="4.2.2" targetFramework="net462" />
      <package id="Microsoft.Owin.Host.HttpListener" version="4.2.2" targetFramework="net462" />
      <package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net462" />
      <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net462" />
      <package id="Owin" version="1.0" targetFramework="net462" />
    packages>
    

    创建Web监听

    主要用于创建WebApi的监听,监听服务后在进行其他配置,在该代码中需要配置传入传出的数据信息和绑定的端口号等。

    1. 在项目中创建HGApplication类,并添加如下代码:

      public class HGApplication
      {
          protected IDisposable WebApplication;
      
          public void Start()
          {
              AppDomain.CurrentDomain.Load(typeof(Microsoft.Owin.Host.HttpListener.OwinHttpListener).Assembly.GetName());
              WebApplication = WebApp.Start("http://*:9555/");
          }
      
          public void Close()
          {
              WebApplication.Dispose();
          }
      }
      
    2. 选择HardwareGateService项目,点击右键->生成依赖项->项目依赖项,选择HardwareGatewayWebApi项目。

      最终会在引用中查看到项目的依赖:

    3. HardwareGateService项目的Program类中添加HGApplication的相关调用

      internal class Application {
          // 添加声明
          HGApplication _host = null;
          internal void Start() {
              System.Console.WriteLine($"Start");
              try
              {
                  // 实例化
                  _host = new HGApplication();
                  // 调用开始方法
                  _host.Start();
              }
              catch (Exception ex)
              {
                  throw new NotImplementedException();
              }
          }
          internal void Stop() {
              System.Console.WriteLine($"Stop");
              if (_host != null)
              {
                  _host.Close();
              }
          }
      }
      

    注意事项

    HttpListener失败

    开始时未添加AppDomain.CurrentDomain.Load(typeof(Microsoft.Owin.Host.HttpListener.OwinHttpListener).Assembly.GetName());代码,Web.Start会报如下错误:

    System.MissingMemberException: The server factory could not be located for the given input: Microsoft.Owin.Host.HttpListener
    

    将Microsoft.Owin.Host.HttpListener更新到了最新版本问题依然存在。

    经过百度,bing查找后发现是Microsoft.Owin.Host.HttpListener必须手动引入,因此添加了该行代码。

    WebApp.Start("http://*:9555/"); 启动失败

    WebApp.Start("http://*:9555/");系统不报错,但是在测试时无法调用到后台,但是使用WebApp.Start("http://localhost:9555/");是可以的,后台根据查询资料发现是权限不够,使用如下代码后发现也不行:

    
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v2">
    	
        <security>
    		<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
    			<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
    	    requestedPrivileges>
        security>
    	<publisherPolicy apply="yes" />
    	<dependentAssembly>
    		<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    		<bindingRedirect oldVersion="0.0.0.0-4.2.2.0" newVersion="4.2.2.0" />
    	dependentAssembly>
    assemblyBinding>
    
    

    在找资料时有篇文章说需要系统管理员权限,因此才恍然大悟,只需要使用管理员打开vs2022,然后打开本项目即可。

    增加Owin的配置文件

    在添加监听后,可以自定义配置信息,为了以后更加方便,因此将传入和传出的类型改为了JSON方式。并添加了两种访问模式。

    创建Startup类,代码如下:

    // namespace 上添加该代码,HardwareGatewayWebApi.Startup为空间.该类
    [assembly: OwinStartup(typeof(HardwareGatewayWebApi.Startup))]
    
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888
            HttpConfiguration config = new HttpConfiguration();
            config.Formatters.Clear();
            // 主要添加了Json格式化的相关信息
            config.Formatters.Add(new JsonMediaTypeFormatter());
            config.Formatters.JsonFormatter.SerializerSettings =
            new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
            ////干掉xml序列号器
            //config.Formatters.Remove(config.Formatters.XmlFormatter);
            ////解决json序列号时的循环问题
            //config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            ////对json数据使用混合大小写 驼峰式
            //config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            ////跟属性名同样大小输出
            //config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver();
            // 增加自定义的访问配置
            config.MapHttpAttributeRoutes();
            // 通用访问配置
            config.Routes.MapHttpRoute(
                name: "default",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
                );
            app.UseWebApi(config);
        }
    }
    

    创建通用访问配置

    通用配置的名称需要以Controller结尾,通过设置的配置信息方法名为{action},参数等可进行自定义,本例为测试。

    在HardwareGateWebApi项目中添加controller文件夹,在该文件夹中添加TestController类,代码如下:

    public class TestController : ApiController
    {
        [HttpGet]
        public String Get()
        {
            return "HelloWorld";
        }
    
        [HttpGet]
        public string Get(int id)
        {
            return $"收到数据{id}";
        }
    
        public string Post([FromBody] string data)
        {
            return data;
        }
    
        public string Delete(int id)
        {
            return $"delete数据{id}"; ;
        }
    }
    

    当系统运行时访问http://localhost:9555/api/test/get/33,即可得到返回数据

    创建自定义访问配置

    通过自定义Route来设置路由,通过HttpGetHttpPost等标签来定义访问的方式。

    在controller文件夹中添加HardwareGatewayController类,并添加测试代码

    public class HardwareGatewayController : ApiController
    {
        [HttpGet]
        [Route("HardwareGateway/HelloWorld")]
        public AjaxResult HelloWorld()
        {
            return AjaxResult.success($"HelloWorld") ;
        }
    }
    

    当系统运行时访问:http://localhost:9555/HardwareGateway/HelloWorld,会得到如下结果:

    添加调用类型AjaxResult

    在自定义访问配置中加入了AjaxResult类,用来统一输入和输出,AjaxResult代码如下:

    [DataContract]
    public class AjaxResult
    {
        /**
        * 正常返回
        */
        public const int OK = 0;
        /// 
        /// 警告
        /// 
        public const int WARN = 301;
        /**
            * 异常
            */
        public const int ERROR = 500;
    
        /// 
        /// 状态码
        /// 
        [DataMember]
        public int code { get; set; }
        /// 
        /// 返回内容
        /// 
        [DataMember]
        public String msg { get; set; }
        /// 
        /// 数据对象
        /// 
        [DataMember]
        public Object data { get; set; }
        /**
            * 无惨构造
            */
        public AjaxResult() { }
    
        /**
            *填充正确结果
            * @param data
            * @return
            */
        public static AjaxResult success(string strData)
        {
            return success(strData, "成功");
        }
    
        public static AjaxResult success(Object objData)
        {
            return success(JsonConvert.SerializeObject(objData), "成功");//JsonConvert.SerializeObject()
        }
    
        /**
            * 填充错误结果
            * @param data 数据
            * @param message 开发者信息
            * @return 错误结果描述
            */
        public static AjaxResult error(String strData, string message)
        {
            return new AjaxResult(strData, ERROR, string.IsNullOrEmpty(message) ? "失败" : message);
        }
    
        /**
        * 填充错误结果
        * @param data 数据
        * @param message 开发者信息
        * @return 错误结果描述
        */
        public static AjaxResult error(Object strData, string message)
        {
            return new AjaxResult(strData, ERROR, string.IsNullOrEmpty(message) ? "失败" : message);
        }
    
        /**
            * 填充正确结果
            * @param data 数据
            * @param message 信息
            * @return 正确结果描述
            */
        public static AjaxResult success(Object objData, String message)
        {
            return new AjaxResult(objData, OK, string.IsNullOrEmpty(message) ? "成功" : message);
        }
    
        /**
            * 带参数的构造
            * @param data
            * @param code
            * @param message
            */
        AjaxResult(Object objData, int code, String message)
        {
            this.data = objData;
            this.code = code;
            this.msg = message;
        }
    
    }
    

    注:该代码的起源与ruoyi项目,因为上位机项目是java开发,因此进行了传参的统一。

    结尾

    自此,公共项目完成了初步搭建,后续将在公共项目添加硬件网关的相关代码。

    该代码下载地址:https://github.com/wanghun315/HardwareGatewayProject_V1.0

  • 相关阅读:
    数据结构--冰壶C++
    “华为杯”研究生数学建模竞赛2019年-【华为杯】F题:智能飞行器航迹规划模型(附优秀论文及Pyhton代码实现)
    VSCode配置msvc编译调试环境
    编译和链接
    代码随想录算法训练营第25天|216.组合总和III 17.电话号码的字母组合
    牛客刷题——剑指offer(第三期)
    广州蓝景分享—「web前端素材」使用CSS动画效果(下)
    ABP vNext系列文章03---依赖注入
    [原创]移远RM500U-CN模组驱动移植
    2022年智慧城市行业概括及现状
  • 原文地址:https://www.cnblogs.com/wanghun315/p/17592079.html