園子里有同學介紹 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}"); } }