在 Windows 窗体应用程序中托管 ASP.NET Core API

Mat*_*ing 11 .net c# winforms asp.net-core asp.net-core-webapi

背景:我正在处理一个涉及 WinForms 应用程序的项目。客户端想要公开一个仅限本地的 HTTP 服务器,以允许其他应用程序通过 REST API(或类似的)在 WinForms 应用程序的运行实例上触发功能。首选是使用 ASP.NET Core 实现上述 API。

因此,我的问题是:如何构建一个项目以在同一进程中同时拥有 ASP.NET Core API 和 WinForms GUI?有什么陷阱我需要警惕吗?

Rez*_*aei 18

在 Windows 窗体应用程序中托管 ASP.NET CORE API 并与窗体交互

下面是一个基本的分步示例,介绍如何创建项目以在 Windows 窗体应用程序中托管 ASP.NET CORE API 并执行与窗体的一些交互。

为此,请按照下列步骤操作:

  1. 创建一个 Windows 窗体应用程序命名它 MyWinFormsApp
  2. Form1在设计模式下打开并在其TextBox上放置一个。
  3. 将设计器中的Modifiers属性更改textBox1Public并保存。
  4. 安装Microsoft.AspNetCore.Mvc
  5. 安装Microsoft.AspNetCore
  6. 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();
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  7. 将以下代码复制到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>();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  8. Controllers在项目的根目录中创建一个文件夹。

  9. ValuesController.csControllers文件夹中创建并将以下代码复制到文件中:

    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();
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  10. 运行应用程序。

  11. 输入“你好” textBox1
  12. 打开浏览器并浏览http://localhost:5000/api/values ? 你会看到hi作为回应。
  13. http://localhost:5000/api/values/bye ? 你会byetextBox1

  • 正如我在评论中提到的,答案不是关于最佳实践,它更多的是一个 PoC,但是这个解决方案有一些要点:(1)总的来说,这个想法是好的,它是进程间通信。(2) 我在生产环境中的 WinForms 应用程序之间使用了类似的方法,使用 WCF 进行 IPC,没有任何问题。(3)我在测试环境中使用了ASP.NET WEB API来实现此目的,但我还没有使用ASP.NET CORE来实现此目的。(4)只要使用Invoke访问UI线程,尝试访问UI线程就没有问题。 (3认同)
  • 谢谢雷扎,你的回答很有魅力。 (2认同)