【问题标题】:Hosting ASP.NET Core API in a Windows Forms Application在 Windows 窗体应用程序中托管 ASP.NET Core API
【发布时间】: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。与其说是“两个程序”,不如说是同一个程序的两个不同接口。

标签: c# .net winforms asp.net-core asp.net-core-webapi


【解决方案1】:

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

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

为此,请按以下步骤操作:

  1. 创建一个 Windows 窗体应用程序,将其命名为 MyWinFormsApp

  2. 在设计模式下打开Form1,然后在上面放一个TextBox

  3. 将设计器中textBox1Modifiers属性更改为Public并保存。

  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();
             }
         }
     }
    
  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>();
         }
     }
    
  8. 在项目的根目录中创建一个名为Controllers 的文件夹。

  9. 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();
             }
         }
     }
    
  10. 运行应用程序。

  11. textBox1中输入“hi”

  12. 打开浏览器并浏览 http://localhost:5000/api/values → 您将看到 hi 作为响应。

  13. 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 或任何其他消息总线在基于事件/消息的解决方案中的应用程序之间进行通信。 (这超出了本文的范围)
猜你喜欢
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多