Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self hosting HTTP(s) endpoints in .net core app without using asp.net?

I have a .net core application running in Windows and Linux as well (I use .net core runtime >= 2.1). To get better insights I'd like to expose a metrics endpoint (simple HTTP GET endpoint) for Prometheus publishing some internal stats of my application.

Searching through the WWW and SO I always ended up on using asp.net core. Since I only want to add a quite simple HTTP GET endpoint to an existing .net core app it seems a little bit overkill, to port the whole application to asp.net.

The alternative I already considered was to write my own handler based on HttpListener. This is quite straight forward when it comes to a simple HTTP endpoint, but since all information I found regarding SSL and Linux was, this is not supported at the moment and I should go with asp.net. (https://github.com/dotnet/runtime/issues/33288#issuecomment-595812935)

So I'm wondering what I missunderstood! Am I the only one? Is there already a good library providing a simple http(s) server for .net core?

EDIT: [SOLVED] As @ADyson mentioned in the comments below the existing application does not need to be ported to asp.net core!

Project files generated with dotnet new web in version 2.1 automatically added references to "Microsoft.AspNetCore.App" and "Microsoft.AspNetCore.Razor.Design"

When I referenced my asp.net core project from a .net core project and executed the code hosting the web service I ended up with an System.IO.FileNotFoundException stating it "Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core'".

Microsoft.AspNetCore.App is a metapackage also referencing said Microsoft.AspNetCore.MVC! Thus, the executing assembly also has to reference this metapackage. This observation missled me that using asp.net core renders my whole application to be built around Microsoft.AspNetCore.App.

After removing these references and adding only a reference to "Microsoft.AspNetCore" everything works as expected.

After checking the generated project files from dotnet new web in version 3.1 these references were not added. This is not a problem for folks using newer versions of dotnet!

like image 1000
pocketbroadcast Avatar asked Apr 02 '20 09:04

pocketbroadcast


People also ask

What is self hosting in .NET Core?

Self Host just means it uses the built-in Web Server, which is in contrast to classic ASP.NET Framework Web Apps which typically requires IIS or the built-in WebDev server to run.

Can a Web API be self hosting?

Self Hosting. You can host a Web API as separate process than ASP.NET. It means you can host a Web API in console application or windows service or OWIN or any other process that is managed by . NET framework.

Where can I host a .NET Core app for free?

MyASP.NET MyASP.NET allows you to host your ASP.NET website for free completely. You can also host Classic ASP Website for free or latest ASP.NET Core website for free.


3 Answers

As mentioned by @ADyson, OWIN is the way to go. You can easily self-host a HTTP endpoint in your existing application. Here is a sample to self-host it in a .Net Core 3.1 console application. It exposes a simple endpoint listening on port 5000 for GET requests using a controller. All you need is to install the Microsoft.AspNetCore.Owin Nuget package.

The code files structure is as follows:

.
├── Program.cs
├── Startup.cs
├── Controllers
    ├── SayHi.cs

Program.cs

using Microsoft.AspNetCore.Hosting;

namespace WebApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseUrls("http://*:5000")
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

Startup.cs

using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace WebApp
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

SayHi.cs

using Microsoft.AspNetCore.Mvc;

namespace WebApp.Controllers
{
    public class SayHi : ControllerBase
    {
        [Route("sayhi/{name}")]
        public IActionResult Get(string name)
        {
            return Ok($"Hello {name}");
        }
    }
}

Then a simple dotnet WebApp.dll would start the app and web server. As you can see, the sample uses Kestrel. The default web server. You can check Microsoft's related documentation.

For more configuration and routing options you can check Microsoft's documentation.

like image 175
Anouar Avatar answered Oct 16 '22 08:10

Anouar


One option is to use EmbeddIo

https://unosquare.github.io/embedio/

I find the documentation is not always the best, especially as they recently upgrade and many samples etc. are not valid. But you can get there!

You can self host a REST API like this:

 WebServer ws = new WebServer(o => o
        .WithUrlPrefix(url)
        .WithMode(HttpListenerMode.EmbedIO))
        .WithWebApi("/api", m => m
        .WithController<ApiController>());

this.Cts = new CancellationTokenSource();
var task = Webserver.RunAsync(Cts.Token);

Then define your API Controller like this.

class ApiController : WebApiController
 {
        public ApiController() : base()
        {

        }

        [Route(HttpVerbs.Get, "/hello")]
        public async Task HelloWorld()
        {
            string ret;
            try
            {
                ret = "Hello from webserver @ " + DateTime.Now.ToLongTimeString();
            }
            catch (Exception ex)
            {
                //
            }
            await HttpContext.SendDataAsync(ret);

        }
}
like image 35
jason.kaisersmith Avatar answered Oct 16 '22 08:10

jason.kaisersmith


Project files generated with dotnet new web in version 2.1 automatically added references to "Microsoft.AspNetCore.App" and "Microsoft.AspNetCore.Razor.Design" which, when referenced by a .net core project and executed ended up with an System.IO.FileNotFoundException stating it "Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core'".

Creating a project with dotnet new web in version 3.1 does not reference these, thus the project can be referenced and executed from a .net core application.

-> Using asp.net core is a viable solution for me (again)!

like image 2
pocketbroadcast Avatar answered Oct 16 '22 08:10

pocketbroadcast