园子里有同学介绍 BeetleX.FastHttpApi 组件,可以在 应用程序或服务中 搭建 web 服务 ,看起来挺强大的 。 通过 html + css + js 做为应用程序UI ,winform 做为后端,完美替代 WPF + WCF。 搭建要点如下:
1. BeetleX.FastHttpApi 通过 Nuget 包管理器获取。 其宿主环境需运行在 .net framework 4.6.1 以上版本。
2. 官方示例下载地址:
https://github.com/IKende/FastHttpApi/tree/master/samples/WinWebSample
控制器示例下载地址:
https://github.com/IKende/FastHttpApi/tree/master/samples/HttpApiServer.HttpAndWebsocketApi
https://github.com/IKende/FastHttpApi/blob/master/Extend/BeetleX.FastHttpApi.Admin/AdminController.cs
3.web 服务器默认将 views 文件夹做为 root 目录 , 通过 HttpOptions.StaticResourcePath 参数值调整 root 路径 ,也可通过 HttpApiServer.Debug 调整该参数。
4.BeetleX.FastHttpApi 启动时,会将包含 Controller 属性类都做为控制器方法 , 通过 BaseUrl 指定 调用方法路径。
控置器与前端脚本交互示例:
[Controller(BaseUrl = "course/")] public class WebAction { public object GetStarted(string email) { return new TextResult($"{email} {DateTime.Now}"); } [NotAction] public void Init(BeetleX.FastHttpApi.HttpApiServer server,string path) { mServer = server; } [Post] public bool EditEmployee(int id,Employee emp, IHttpContext context) { Employee record = mEmployees.Find(e => e.EmployeeID == id); if (record != null) { record.City = emp.City; record.Address = emp.Address; record.Title = emp.Title; record.HomePhone = emp.HomePhone; return true; } return false; } }
前端调用:
function GetStarted(email) { $.get('/course/GetStarted?email=' + email, function (result) { alert(result); }); }
Controller 类,设置 SingleInstance 可配置为单例模式 , BaseUrl 设定路由地址。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] public class ControllerAttribute : Attribute { public string BaseUrl { get; set; } public bool SingleInstance { get; set; } public ControllerAttribute() { SingleInstance = true; } }
5. 在 winform 中 通过 WebBrower 访问Web 服务,可通过如下方法设置IE 版本,否则默认 WebBrower 版本是 IE7 。
private void SetIE() { int BrowserVer, RegVal; BrowserVer = webBrowser1.Version.Major; if (BrowserVer >= 11) RegVal = 11001; else if (BrowserVer == 10) RegVal = 10001; else if (BrowserVer == 9) RegVal = 9999; else if (BrowserVer == 8) RegVal = 8888; else RegVal = 7000; string productName = AppDomain.CurrentDomain.SetupInformation.ApplicationName;//获取程序名称 RegistryKey key = Registry.CurrentUser; RegistryKey software = key.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION\" + productName); if (software != null) { software.Close(); software.Dispose(); } RegistryKey wwui = key.OpenSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", true); if (wwui != null) wwui.SetValue(productName, RegVal, RegistryValueKind.DWord); webBrowser1.Url = new Uri("http://192.168.1.178:12345"); }
6.在应用程序根目录 添加 HttpConfig.json做为 服务初使化配置,注意 通过 Host 可限制网络访问权限。
{ "HttpConfig": { "Host": "0.0.0.0", "Port": 12345, "SSL": false, "CertificateFile": "", "CertificatePassword": "", "MaxBodyLength": 20097152, "OutputStackTrace": true, "StaticResurceType": "xml;svg;woff;woff2;jpg;jpeg;gif;png;js;html;htm;css;txt;ico;zip;rar", "DefaultPage": "index.html;index.htm", "NotLoadFolder": "\\Files;\\Images;\\Data", "NoGzipFiles": "xml;svg;woff;woff2;jpg;jpeg;gif;png;js;html;htm;css;txt;ico;zip;rar", "CacheFiles": "", "BufferSize": 8192, "WebSocketMaxRPS": 2000, "WriteLog": true, "LogToConsole": true, "LogLevel": "Warring" } }
7. BeetleX.FastHttpApi 服务与 Winform(宿主) 交互,如关闭窗体,控制 winform 控件等 , 这里有几种思路:
1.可以通过消息中间件(MQ)实现
2.通过c# 自带事件实现,如:
/// <summary> /// 全局静态资源类 /// </summary> public class UIResource { System.Windows.Forms.Control control; public event EventHandler EventHanderForm; public UIResource(System.Windows.Forms.Control control) { this.control = control; } /// <summary> /// 关闭窗口 /// </summary> public void ActionForm() { if (EventHanderForm != null) { if (control.InvokeRequired) { control.Invoke(new Action(() => { EventHanderForm(null, null); })); } else { EventHanderForm(null, null); } } } }
static UIResource uiResource; public Form1() { InitializeComponent(); if (uiResource == null) { uiResource = new UIResource(this); uiResource.EventHanderForm += UiResource_eventHander; } } private void UiResource_eventHander(object sender, EventArgs e) { //隐藏主窗体 formCursor.Hide(); //弹出新窗体 Form1 f = new Form1(); f.Show(); } [Controller(BaseUrl = "course/")] public class WebAction { public object GetStarted(string email) { //触发事件 uiResource.ActionForm(); return new TextResult($"{email} {DateTime.Now}"); } }
3.宿主资源静态化,通过 Invoke 实现。
[Controller(BaseUrl = "course/")] public class WebAction { public object GetStarted(string email) { formCursor.Invoke(new Action(() => { //隐藏主窗体 formCursor.Hide(); //弹出新窗体 Form1 f = new Form1(); f.Show(); })); return new TextResult($"{email} {DateTime.Now}"); } }