Background: I am working on a project that involves a WinForms app. The client wants to expose a local-only HTTP server to allow other apps to trigger functionality on a running instance of the WinForms app via a REST API (or similar). The preference is to implement the aforementioned API using ASP.NET Core.
My question is thus: How do I structure a project to have both an ASP.NET Core API and a WinForms GUI in the same process? Are there any pitfalls I'd have to be wary of?
Windows Forms support was added to . NET Core in version 3.0.
Here, we will be talking about an example to create a Web API and call it, using a desktop client application. Start Visual Studio and go to File -> New -> Project. In the template panel select Installed -> Templates -> Visual C# -> Web -> ASP.NET Web Application.
Hosting ASP.NET CORE API in a Windows Forms Application and Interaction with Form
Here is a basic step by step example about how to create a project to host ASP.NET CORE API inside a Windows Forms Application and perform some interaction with Form.
To do so, follow these steps:
Create a Windows Forms Application name it MyWinFormsApp
Open Form1 in design mode and drop a TextBox on it.
Change the Modifiers property of the textBox1 in designer to Public and save it.
Install Microsoft.AspNetCore.Mvc package
Install Microsoft.AspNetCore package
Create a Startup.cs file in the root of the project, and copy the following code:
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();
}
}
}
Copy the following code in 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>();
}
}
Create a folder called Controllers in the root of the project.
Create ValuesController.cs in the Controllers folder and copy the following code to file:
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 the application.
Type "hi" in the textBox1
Open browser and browse http://localhost:5000/api/values → You will see hi as response.
http://localhost:5000/api/values/bye → You will see bye in textBox1
Further Reading
You may also be interested in How to use Dependency Injection (DI) in Windows Forms (WinForms)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With