简体   繁体   English

如何编写 Web API、自托管、Windows 服务

[英]How to write Web API, Self hosting, Windows Service

I can't make sense of this.我无法理解这一点。 I keep getting an exception我不断收到例外

Exception thrown: 'System.AggregateException' in mscorlib.dll, with a message: "Internal error in the expression evaluator."抛出异常:mscorlib.dll 中的“System.AggregateException”,并显示一条消息:“表达式计算器中的内部错误。” and no Inner Exception!并且没有内部异常!

I can't find where the error is coming from other than when the server is being started, this Line: _server.OpenAsync().Wait();除了服务器启动时,我找不到错误来自哪里,这一行:_server.OpenAsync().Wait();

I thought it would be a good idea to use DI and I though my problems were coming from Autofac but as you can see I have remarked it all out and I'm still getting this exception.我认为使用 DI 是个好主意,虽然我的问题来自 Autofac,但正如您所看到的,我已经将其全部注释掉了,但我仍然遇到此异常。 The pertinent code is in the last method.相关代码在最后一个方法中。 Please take a look at the code:请看一下代码:

using System;
using System.ServiceProcess;
using System.Threading;
using System.Reflection;
using ServicesUtilities;
using System.Web.Http;
using System.Web.Http.SelfHost;
using Autofac;
using Autofac.Integration.WebApi;

namespace SeviceMerge
{

    partial class MergeService : ServiceBase, IQuasiServiceBase
    {
        private HttpSelfHostServer _server;
        private bool _runOnStart;
        public InjectionService()
        {
            InitializeComponent();
            _runOnStart = Config.Run;
        }

        protected override void OnStart(string[] args)
        {
            WebApiListener();
        }

        protected override void OnStop()
        {
            _runOnStart = false;

            _server.CloseAsync().Wait();
            _server.Dispose();
        }
        void IQuasiServiceBase.OnStart(string[] args, bool isBatchMode)
        {
            OnStart(args);
        }

        void IQuasiServiceBase.OnStop()
        {
            OnStop();
        }

        bool IQuasiServiceBase.PauseCheck()
        {
            return false;
        }

        bool IQuasiServiceBase.StopCheck()
        {
            return false;
        }

        private void WebApiListener()
        {
            var config = new HttpSelfHostConfiguration("http://localhost:26675");

            config.Routes.MapHttpRoute(
                "Presents",
                "api/{controler}/{id}",
                new { id = RouteParameter.Optional }
            );

            _server = new HttpSelfHostServer(config);
            _server.OpenAsync().Wait();
        }
    }
}

Here's my Controller code:这是我的控制器代码:

using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace AEMtoParmedInject.Controllers
{
    public class AemToParmedMergeController : ApiController
    {
        private ILogger _logger;
        private IWorkTheMachine _worker;
        public AemToParmedMergeController()
        {
            _logger = new Logger();
            //_worker = worker;
        }

        [HttpGet]
        public HttpResponseMessage Index()
        {
            return new HttpResponseMessage()
            {
                Content = new StringContent(
                    "<html>" +
                        "<head>" +
                        "</head>" +
                        "<body>" +
                            "<p>By click on the button below you are signaling the AEM to Parmed Merge service to perform it task</p>" +
                            "<form>" +
                                "<input type='submit' action='Index' value='Integrate AEM Content'>" +
                            "</form" +
                        "</body>" +
                    "</html>",
                    Encoding.UTF8,
                    "text/html"
                )
            };
        }
    }
}

Everything in .net core starts with a simple console application and here I give you 5 simple steps that you can use in order to self-host a Web API / Web APP in a worker service and host the final .exe in your windows services, even you can host in Linux Systemd with little changes. .net core 中的一切都从一个简单的控制台应用程序开始,在这里我给你 5 个简单的步骤,你可以使用这些步骤在工作服务中自托管一个 Web API/Web APP,并在你的 Windows 服务中托管最终的 .exe,甚至你可以在 Linux Systemd 中托管,只需稍作改动。

I've created a very simple Worker-Service Web-API template that exists in my GitHub profile.我创建了一个非常简单的 Worker-Service Web-API 模板,它存在于我的 GitHub 个人资料中。 The following steps work 100%, but if you faced any problem, you can ask here or you can clone the template from my GitHub and use it and read the documentation there.以下步骤 100% 有效,但如果您遇到任何问题,您可以在这里提问,或者您可以从我的 GitHub 克隆模板并使用它并阅读那里的文档。

Do the following steps:执行以下步骤:

  1. Create a .net core console application.创建 .net 核心控制台应用程序。
  2. Install packages "Microsoft.AspNetCore.App" and "Microsoft.Extensions.Hosting.WindowsServices" using NuGet.使用 NuGet 安装包“Microsoft.AspNetCore.App”和“Microsoft.Extensions.Hosting.WindowsServices”。
  3. Create a Worker.cs file which will handle your worker service.创建一个 Worker.cs 文件来处理您的工作器服务。 put the following codes inside:将以下代码放入:
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace WorkerServiceWebAppTemplate
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }
}
  1. Create a Startup.cs file which will handle your web host and create a simple GET API in the root address and responsible to show a simple message.创建一个 Startup.cs 文件,该文件将处理您的 Web 主机并在根地址中创建一个简单的 GET API,并负责显示一条简单的消息。 you can extend it.你可以扩展它。 put the following lines of codes in your Startup.cs file:将以下代码行放入 Startup.cs 文件中:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;

namespace WorkerServiceWebAppTemplate
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();
            else
                app.UseHsts();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}
  1. Finally to start worker service and host your Web API inside your worker service, and also in order yo allow your published .exe file to be able to be host in windows services, use the following codes in your Program.cs:最后要启动工作服务并在工作服务中托管您的 Web API,并且为了让您发布的 .exe 文件能够在 Windows 服务中托管,请在您的 Program.cs 中使用以下代码:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WorkerServiceWebAppTemplate
{
    class Program
    {
        static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        private static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureServices((hostBuilderContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
    }
}

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

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