简体   繁体   English

.net 核心应用程序中的自托管 HTTP(s) 端点而不使用 asp.net?

[英]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).我还有一个在 Windows 和 Linux 中运行的 .net 核心应用程序(我使用 .net 核心运行时 >= 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.为了获得更好的见解,我想公开一个指标端点(简单的 HTTP GET 端点),以便 Prometheus 发布我的应用程序的一些内部统计信息。

Searching through the WWW and SO I always ended up on using asp.net core.通过 WWW 和 SO 搜索,我总是最终使用 asp.net 核心。 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.由于我只想向现有的 .net 核心应用程序添加一个非常简单的 HTTP GET 端点,因此将整个应用程序移植到 asp.net 似乎有点过头了。

The alternative I already considered was to write my own handler based on HttpListener.我已经考虑过的替代方法是基于 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.当涉及到一个简单的 HTTP 端点时,这是非常直接的,但是由于我发现的所有关于 SSL 和 Linux 的信息都是如此,目前不支持这,我应该使用 asp.net。 ( https://github.com/dotnet/runtime/issues/33288#issuecomment-595812935 ) ( 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?是否已经有一个很好的库为 .net 核心提供了一个简单的 http(s) 服务器?

EDIT: [SOLVED] As @ADyson mentioned in the comments below the existing application does not need to be ported to asp.net core!编辑: [已解决]正如@ADyson 在下面的评论中提到的,现有应用程序不需要移植到 asp.net 核心!

Project files generated with dotnet new web in version 2.1 automatically added references to "Microsoft.AspNetCore.App" and "Microsoft.AspNetCore.Razor.Design"在 2.1 版中使用dotnet new web生成的项目文件自动添加了对"Microsoft.AspNetCore.App""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'" .当我从 .net 核心项目引用我的 asp.net 核心项目并执行托管 Web 服务的代码时,我最终得到了一个System.IO.FileNotFoundException指出它"Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core'"

Microsoft.AspNetCore.App is a metapackage also referencing said Microsoft.AspNetCore.MVC ! Microsoft.AspNetCore.App是一个元包,也引用了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 .这个观察误导了我,使用 asp.net core 会使我的整个应用程序围绕Microsoft.AspNetCore.App构建。

After removing these references and adding only a reference to "Microsoft.AspNetCore" everything works as expected.删除这些引用并仅添加对"Microsoft.AspNetCore"的引用后,一切都按预期工作。

After checking the generated project files from dotnet new web in version 3.1 these references were not added.在 3.1 版中检查从dotnet new web生成的项目文件后,这些引用没有被添加。 This is not a problem for folks using newer versions of dotnet!对于使用较新版本 dotnet 的人来说,这不是问题!

As mentioned by @ADyson , OWIN is the way to go.正如@ADyson所提到的,OWIN 是要走的路。 You can easily self-host a HTTP endpoint in your existing application.您可以轻松地在现有应用程序中自托管 HTTP 端点。 Here is a sample to self-host it in a .Net Core 3.1 console application.这是在 .Net Core 3.1 控制台应用程序中自托管它的示例。 It exposes a simple endpoint listening on port 5000 for GET requests using a controller.它公开了一个简单的端点,用于使用控制器在端口 5000 上侦听 GET 请求。 All you need is to install the Microsoft.AspNetCore.Owin Nuget package.您只需要安装Microsoft.AspNetCore.Owin Nuget 包。

The code files structure is as follows:代码文件结构如下:

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

Program.cs程序.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.然后一个简单的dotnet WebApp.dll将启动应用程序和 Web 服务器。 As you can see, the sample uses Kestrel.如您所见,该示例使用 Kestrel。 The default web server.默认的网络服务器。 You can check Microsoft 's related documentation.您可以查看Microsoft的相关文档。

For more configuration and routing options you can check Microsoft 's documentation.有关更多配置和路由选项,您可以查看Microsoft的文档。

One option is to use EmbeddIo一种选择是使用 EmbeddIo

https://unosquare.github.io/embedio/ 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:您可以像这样自托管 REST API:

 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.然后像这样定义你的 API 控制器。

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);

        }
}

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'" .在 2.1 版中使用dotnet new web生成的项目文件自动添加了对"Microsoft.AspNetCore.App""Microsoft.AspNetCore.Razor.Design"引用,当被 .net 核心项目引用并执行时,它们以System.IO.FileNotFoundException结束System.IO.FileNotFoundException声明"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.在 3.1 版本中使用dotnet new web创建项目不引用这些,因此可以从 .net core 应用程序引用和执行该项目。

-> Using asp.net core is a viable solution for me (again)! -> 使用 asp.net core 对我来说是一个可行的解决方案(再次)!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM