C#桌面程序(winform)如何一步步集成内置WebApi(owin技术),解耦IIS,并将Api接收信息推给桌面窗体控件展示

最近工厂有个需求,服务器上部署了一个服务,此服务要把信息推送给现场多台工控机上的CS上位机程序。由于涉及到多个软件之间的通信,做架构时,首先排除掉中间表形式,从效率和稳定性上也排除掉了Socket,最后采用了WebApi接口形式来做通信。但是有个问题,上位机程序都为运行稳定的CS架构程序,当时并没有考虑后台服务WebApi的需求。如果现在给每个上位机程序再做个后端WebApi部署在IIS上,那势必会造成很多开发资源浪费(制造业IT嘛,本身开发就那么几个,呵呵~)。 所以后来思考,能不能做个内置WebApi的dll包,方法事件都写好,上位机软件只要加载这个dll包就能在本地上位机上跑WebApi服务,接收并处理WebApi接收到的消息,大大减小大家的开发工作量。结果还真有办法,就是使用owin技术。owin是什么,大家可以百度下,大致意思就是它允许你在本地运行WebService,从而解耦web服务器IIS。 那怎么集成owin呢,方法如下:

一、创建dll项目及导入所需依赖库

打开VS,建立class library项目,命名为OWINServer 打开Nuget,导入下列所需依赖库

二、建立Startup类

在OWINServer项目中,创建第一个类Startup类,用以启动owin

public class Startup

{

public void Configuration(IAppBuilder appBuilder)

{

try

{

HttpConfiguration config = new HttpConfiguration();

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

config.Routes.MapHttpRoute(

name: "DefaultApi",

routeTemplate: "api/{controller}/{id}",

defaults: new { id = RouteParameter.Optional }

);

appBuilder.UseWebApi(config);

}

catch (Exception ex)

{

throw ex;

}

}

}

三、建立事件类TriggerEvent

在OWINServer项目中,建立第二个类OWINTriggerEvent事件类,用来保存接口收到的信息,并用事件触发的方式将收到的接口信息通知桌面应用。

public class OWINTriggerEvent

{

public delegate void GetInfoEventHandler(object sender, EventArgs e);

public event GetInfoEventHandler infoEvent;

//存储信息变量

public string Message = "";

//编写引发事件的函数(在程序任意域使用)

public void OnMessage()

{

if (infoEvent != null)

{

//发送信息

infoEvent(this, new EventArgs());

}

}

}

四、建立ApiController接口类

在OWINServer项目中,建立第三个类OWINApiController,用以实现被外部调用的接口。当收到信息后触发OWINTriggerEvent事件,将消息传给桌面前端应用。

public class OWINApiController : ApiController

{

// GET api/

public IEnumerable Get()

{

return new string[] { "Success"};

}

// GET api//5

public string Get(int id)

{

return string.Format("owin {0} by:linezero", id);

}

// POST api/

public string Post([FromBody] string value)

{

//将接收到的信息赋给事件类中Message属性

OWINStart.TriggerEvent.Message = value;

//触发事件类中事件,将消息传递给桌面程序绑定的方法

OWINStart.TriggerEvent.OnMessage();

return "Success";

}

// PUT api//5

public string Put([FromBody] string value)

{

return "Success";

}

// DELETE api//5

public string Delete([FromBody] string value)

{

return "Success";

}

}

这里只在Post接口里,写了简单接收消息和触发事件的代码,各位可根据需要在里面写其他逻辑代码,但还是建议里面不多写逻辑,功能界限只作为消息传递,将消息传递给桌面前端后,由前端对消息进行分析处理。

五、建立OWINStart类

上面3个工具类写完后,再写个集成类OWINStart,用以对以上3个类集成,作为对外的唯一调用类,方便第三方软件对OWINServer.dll的使用。

public class OWINStart

{

public static OWINTriggerEvent TriggerEvent { get; set; }

public static OWINTriggerEvent Start(string ServerUrl)

{

try

{

//调用Startup启动owin,url需要调用方传入

WebApp.Start(url: ServerUrl);

//新建OWINTriggerEvent类实例,并返回被调用方使用获取里面的message和infoEvent事件

var triggerEvent = new OWINTriggerEvent();

TriggerEvent = triggerEvent;

HttpClient client = new HttpClient();

//通过get请求数据,测试owin服务是否正常开启

var response = client.GetAsync(ServerUrl+"api/owinapi").Result;

if (response.IsSuccessStatusCode)

{

return triggerEvent;

}

else

{

throw new Exception("Owin loacal server start failed!");

}

}

catch (Exception)

{

throw;

}

}

}

六、编译OWINServer项目,获得dll文件

项目结构如下,直接编译项目

获得如下dll文件 OWINServer.dll包通过前面6步就已经生成了,下面就是创建个桌面引用,集成并测试一下它好不好用了~

七、新建桌面项目,导入OWINServer.dll

新建一个owin的桌面项目,将OWINServer.dll包导入 简单画几个桌面控件,按钮用来启动owin,一个输入框用来输入开启的owin服务的url地址,另一个用来显示接口接到的消息。

八、启动owin服务,接收并显示消息

在winform后端写如下代码,调用OWINStart.Start启用owin服务,并给infoEvent事件绑定处理方法GetInfo()。

public partial class Form1 : Form

{

private OWINTriggerEvent _triggerEvent;

public Form1()

{

InitializeComponent();

}

private void Start_button_Click(object sender, EventArgs e)

{

try

{

if (textBox2.Text != "")

{

;

string baseAddress = "http://" + textBox2.Text + ":9121/";

_triggerEvent = OWINStart.Start(baseAddress);

_triggerEvent.infoEvent += GetInfo;

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

private void GetInfo(object sender, EventArgs e)

{

try

{

//将接口收到的消息传给textbox控件

Action actionDelegate = () => { this.textBox1.Text = _triggerEvent.Message; };

this.textBox1.Invoke(actionDelegate);

}

catch (Exception ex)

{

throw;

}

}

}

写完后,运行winform,点击Start按钮,随后打开postman进行接口调试。 可以发现postman成功的将信息通过调用owin接口,将信息传给了桌面的textbox控件。

九、注意事项

(1)调用OWINServer.dll可能会报找不到依赖包的错误,请检查第6步中的dll包是否都放在你的项目dll文件夹中和OWINServer.dll文件在一起。 如果还是报Could not load file or assembly ‘Microsoft.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)":"Microsoft.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35错误 请在app.config中加如以下指向代码:

(2)最近在调试中又出现一个新的问题,发现在调试程序的时候WebApp.Start(url: ServerUrl)可以成功执行,并开启服务。但是跑生成的执行程序时就会报异常错误,啥异常也没说明,只是报内部异常。尝试了N多次,加了N个log也没找到问题,最后查阅资料,发现这原来是缺少管理员权限,而引起了一个被拒绝的内部异常。用管理员权限打开执行程序可以正常开启服务并打开程序。

结语

以上就实现了桌面程序内置WebApi,可以用来进行软件之间的通信。当有软件需要使用此webApi功能时,只要导入这个OWINServer.dll包即可。 dll包下载地址:https://download.csdn.net/download/weixin_44239774/87155725 欢迎各位留言交流,需要源代码和dll包的可以留下邮箱~

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: