winformsasp.net-core-webapikestrel-http-serverself-hosting.net-9.0

Self-hosting (using Kestrel) Web API restful service in .NET 9 Windows Forms app


I've spent quite some time looking on Internet for the subject sample projects/tutorials but I've not found any.

I have a working app implementing a .NET Framework 4.x self-hosted OWIN Winforms App but for .NET 9 I wanted to have a native Kestrel self-hosted Windows Forms app.

For starters I have created a .NET 9 Windows Forms and then I have tried to copy the code from a .NET 9 Web API project into Windows Forms project. I have also installed two NuGet packages:

Microsoft.AspNetCore 
Microsoft.AspNetCore.Hosting

but for the WebApplication class, I'm getting a run-time error:

CS0103: The name WebApplication does not exist in the current context

I checked nuget's Microsoft.AspNetCore.App package hoping it will help to resolve the WebApplication name but AFAIS the Microsoft.AspNetCore.App nuget package is deprecated.

I do realize that just resolving WebApplication name would not bring me a working solution, so I'm looking for a real sample app running a self-hosted Kestrel (restful) Web API within a .NET 9 Windows Forms application. (.NET 6 / .NET 7 / .NET 8 are expected to be also OK, but .NET 9 would be the best).


Solution

  • To find the right solution, actually you need to understand why "the Microsoft.AspNetCore.App nuget package is deprecated".

    The framework packages are part of the SDKs, so now you should acquire them from your local SDK installation, instead of downloading from NuGet.org.

    Thus, open up your WinForms app's project file, and add a FrameworkReference, so that MSBuild understands where to locate Microsoft.AspNetCore.App from the disk.

    <Project Sdk="Microsoft.NET.Sdk">
    
     <PropertyGroup>
       <OutputType>WinExe</OutputType>
       <TargetFramework>net9.0-windows</TargetFramework>
       <RootNamespace>test_winforms_kestrel</RootNamespace>
       <Nullable>enable</Nullable>
       <UseWindowsForms>true</UseWindowsForms>
       <ImplicitUsings>enable</ImplicitUsings>
     </PropertyGroup>
    
     <ItemGroup>
       <FrameworkReference Include="Microsoft.AspNetCore.App" />
     </ItemGroup>
    
    </Project>
    

    Change your Main method to

    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        WebApplication app = WebApplication.Create(new string[] { });
        app.MapGet("/", () => "Hello World!");
        app.RunAsync("http://localhost:7076");
    
        // To customize application configuration such as set high DPI settings or default font,
        // see https://aka.ms/applicationconfiguration.
        ApplicationConfiguration.Initialize();
        Application.Run(new Form1());
    }
    

    And now while you can see your WinForms app, the Web app is also running behind the scene.