在 Windows 窗体应用程序中托管 ASP.NET Core API
Posted
技术标签:
【中文标题】在 Windows 窗体应用程序中托管 ASP.NET Core API【英文标题】:Hosting ASP.NET Core API in a Windows Forms Application 【发布时间】:2020-05-18 21:16:34 【问题描述】:背景:我正在处理一个涉及 WinForms 应用程序的项目。客户端希望公开一个仅限本地的 HTTP 服务器,以允许其他应用程序通过 REST API(或类似方法)在 WinForms 应用程序的运行实例上触发功能。首选是使用 ASP.NET Core 实现上述 API。
因此,我的问题是:如何构建一个项目以在同一进程中同时拥有 ASP.NET Core API 和 WinForms GUI?有什么我需要提防的陷阱吗?
【问题讨论】:
为什么要在同一个进程中运行这两个程序? @citronas 允许其他应用程序通过 REST API 在 WinForms 应用程序的运行实例上触发功能,基本上是进程间通信。 @Matthew 以“最好的方法是什么...”开头的问题通常是题外话,因为它们是基于意见的。您对特定问题有任何具体问题吗? @RezaAghaei 抱歉,用“我该怎么做”替换“什么是最好的方法”......虽然,鉴于绝大多数编程问题都有不止一个解决方案,我认为几乎每个问题都有一个隐含的“什么是最好的方法”组件:-) @citronas 就像 Reza Aghaei 回答的那样 - IPC。与其说是“两个程序”,不如说是同一个程序的两个不同接口。 【参考方案1】:在 Windows 窗体应用程序中托管 ASP.NET CORE API 并与窗体交互
这是一个关于如何创建项目以在 Windows 窗体应用程序中托管 ASP.NET CORE API 并与窗体执行一些交互的基本分步示例。
为此,请按以下步骤操作:
创建一个 Windows 窗体应用程序,将其命名为 MyWinFormsApp
在设计模式下打开Form1
,然后在上面放一个TextBox
。
将设计器中textBox1
的Modifiers
属性更改为Public
并保存。
安装Microsoft.AspNetCore.Mvc
包
安装Microsoft.AspNetCore
包
在项目根目录下创建Startup.cs
文件,复制如下代码:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace MyWinFormsApp
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
public void ConfigureServices(IServiceCollection services)
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseMvc();
将以下代码复制到Program.cs
:
using System;
using System.Threading;
using System.Windows.Forms;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
namespace MyWinFormsApp
public class Program
public static Form1 MainForm get; private set;
[STAThread]
public static void Main(string[] args)
CreateWebHostBuilder(args).Build().RunAsync();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainForm = new Form1();
Application.Run(MainForm);
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
在项目的根目录中创建一个名为Controllers
的文件夹。
在Controllers
文件夹中创建ValuesController.cs
,并将以下代码复制到文件中:
using System;
using Microsoft.AspNetCore.Mvc;
namespace MyWinFormsApp.Controllers
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
[HttpGet]
public ActionResult<string> Get()
string text = "";
Program.MainForm.Invoke(new Action(() =>
text = Program.MainForm.textBox1.Text;
));
return text;
[HttpGet("id")]
public ActionResult Get(string id)
Program.MainForm.Invoke(new Action(() =>
Program.MainForm.textBox1.Text = id;
));
return Ok();
运行应用程序。
在textBox1
中输入“hi”
打开浏览器并浏览 http://localhost:5000/api/values → 您将看到 hi
作为响应。
http://localhost:5000/api/values/bye → 你会在textBox1
看到bye
进一步阅读
您可能也对How to use Dependency Injection (DI) in Windows Forms (WinForms)感兴趣
【讨论】:
该示例使用 GET 方法只是为了简化浏览器中的测试。您可能希望根据自己的要求使用不同的动词。 这不是关于最佳实践,而是关于快速入门和一个简单的 PoC 展示您可以做什么。 谢谢礼萨。您知道这种方法是否会导致线程模型出现任何问题吗? 正如我在 cmets 中提到的,答案不是关于最佳实践,它更像是一个 PoC,但是关于这个解决方案有一些要点:(1)总的来说,这个想法是可以的,它是跨-进程通信。 (2)我在生产环境中的WinForms应用程序之间使用了类似的方法使用WCF进行IPC,没有任何问题。 (3) 我在测试环境中为此目的使用了 ASP.NET WEB API,但我还没有为此目的使用 ASP.NET CORE。 (4)只要使用Invoke访问UI线程,尝试访问UI线程是没有问题的。 另一个要考虑的选项,您可以考虑使用 MSMQ 或任何其他消息总线在基于事件/消息的解决方案中的应用程序之间进行通信。 (这超出了本文的范围)以上是关于在 Windows 窗体应用程序中托管 ASP.NET Core API的主要内容,如果未能解决你的问题,请参考以下文章
在 Windows 窗体应用程序中托管 ASP.NET Core API
C# Windows 窗体无法在 Windows10 上加载非托管 C++ DLL
在退出之前跟踪 - 并正确结束 - C# - C++/CLI - C++ Windows 窗体应用程序中的本机和托管线程