Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Windows窗体应用程序中托管ASP.NET核心API_C#_.net_Winforms_Asp.net Core_Asp.net Core Webapi - Fatal编程技术网

C# 在Windows窗体应用程序中托管ASP.NET核心API

C# 在Windows窗体应用程序中托管ASP.NET核心API,c#,.net,winforms,asp.net-core,asp.net-core-webapi,C#,.net,Winforms,Asp.net Core,Asp.net Core Webapi,背景:我正在从事一个涉及WinForms应用程序的项目。客户端希望公开仅本地HTTP服务器,以允许其他应用程序通过REST API(或类似应用程序)在WinForms应用程序的运行实例上触发功能。首选使用ASP.NET核心实现上述API 因此,我的问题是:如何构造一个项目,使ASP.NET核心API和WinForms GUI都在同一个过程中?是否有任何我必须警惕的陷阱?在Windows窗体应用程序中托管ASP.NET核心API并与窗体交互 下面是一个基本的分步示例,介绍如何创建一个项目,在Win

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


因此,我的问题是:如何构造一个项目,使ASP.NET核心API和WinForms GUI都在同一个过程中?是否有任何我必须警惕的陷阱?

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

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

为此,请执行以下步骤:

  • 创建Windows窗体应用程序名称it
    MyWinFormsApp
  • 在设计模式下打开
    Form1
    ,并在其上放置一个
    TextBox
  • 将设计器中
    textBox1
    Modifiers
    属性更改为
    Public
    ,然后保存它
  • 安装
    Microsoft.AspNetCore.Mvc
    package
  • 安装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>();
        }
    }
    
  • 运行应用程序

  • 文本框1中键入“hi”
  • 打开浏览器并浏览→ 您将看到
    hi
    作为响应
  • → 您将在
    textBox1

  • 为什么要在同一进程中运行这两个程序?@citronas允许其他应用程序通过REST API(基本上是进程间通信)在WinForms应用程序的运行实例上触发功能。@Matthew以“最佳方式是什么…”开头的问题通常是离题的,因为它们是基于意见的。你对某个问题有什么具体的问题吗?@RezaAghaei抱歉,用“我该怎么做”替换“什么是最好的方法”。。。尽管如此,考虑到绝大多数编程问题都有不止一个解决方案,我认为几乎每个问题都有一个隐含的“最好的方法是什么”组件:-)citronas,这与Reza Aghaei回答的完全一样-IPC。与其说它是“两个程序”,不如说它是同一个程序的两个不同接口。该示例使用GET方法只是为了让在浏览器中测试时保持简单。您可能需要根据自己的需求使用不同的动词。这不是关于最佳实践,而是关于快速入门和一个简单的PoC,展示您可以做什么。谢谢Reza。您知道这种方法是否会导致线程模型出现任何问题吗?正如我在评论中提到的,答案不是关于最佳实践,而是PoC,但是这种解决方案有一些要点:(1)一般来说,这个想法是好的,它是进程间通信。(2) 我在生产环境中的WinForms应用程序之间使用WCF for IPC使用了类似的方法,没有任何问题。(3) 为此,我在测试环境中使用了ASP.NETWebAPI,但还没有使用ASP.NETCore。(4)只要使用调用来访问UI线程,就可以尝试访问UI线程。另一个要考虑的选项,您可以考虑使用MSMQ或任何其他消息总线在基于事件/消息的解决方案之间进行应用程序之间的通信。(不在本岗位范围内)
    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();
            }
        }
    }