在自托管的Web Api项目中看不到我的控制器

问题描述 投票:0回答:1

我创建了一个自托管的web api应用程序,作为Windows服务运行,使用TopShelf和Autofac进行依赖注入。

这是我的StartUp逻辑:

public class ApiShell : IApiShell
{
    public void Start()
    {
        using (WebApp.Start<Startup>("http://localhost:9090"))
        {
            Console.WriteLine($"Web server running at 'http://localhost:9090'");
        }
    }

    internal class Startup
    {
        //Configure Web API for Self-Host
        public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();

            GlobalConfiguration.Configuration
              .EnableSwagger(c => c.SingleApiVersion("v1", "Swagger UI"))
              .EnableSwaggerUi();

            //default route
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });

            app.UseWebApi(config);
        }
    }
}

我按照以下方式启动WebApp:

public class HostService
{
    //when windows service statrts
    public void Start()
    {
        IoC.Container.Resolve<IApiShell>().Start();  //start web app
        IoC.Container.Resolve<IActorSystemShell>().Start();
    }

    //when windows service stops
    public void Stop()
    {
        IoC.Container.Resolve<IActorSystemShell>().Stop();
    }
}

TopShelf配置:

HostFactory.Run(x =>
        {
            x.Service<HostService>(s =>
            {
                s.ConstructUsing(name => new HostService());
                s.WhenStarted(sn => sn.Start());
                s.WhenStopped(sn => sn.Stop());
            });
            x.RunAsLocalSystem();
            x.SetDescription("Sample Service");
            x.SetDisplayName("Sample Service");
            x.SetServiceName("Sample Service");
        });

我的控制器:

public class PingController : ApiController
{
    private IActorSystemShell _actorSystem;

    public PingController(IActorSystemShell actorSystem)
    {
        _actorSystem = actorSystem;
    }

    [HttpGet]
    public async Task<string> Ping()
    {
        var response = await _actorSystem.PingActor.Ask<PingMessages.Pong>(PingMessages.Ping.Instance(), 
            TimeSpan.FromSeconds(10));

        return response.PongMessage;
    }
}

我也安装了Swagger,但是无法使用以下任一尝试访问我的控制器:

http://localhost:9090/api/Ping

http://localhost:9090/swagger

我错过了什么?

c# asp.net asp.net-mvc swagger autofac
1个回答
2
投票

你不能这样做:

using (WebApp.Start<Startup>("http://localhost:9090"))
{
    Console.WriteLine($"Web server running at 'http://localhost:9090'");
}

在写入行之后,在使用中不再有语句,因此使用将关闭,从而停止Web应用程序。这是其中一种情况,即使WebApp.Start的结果是IDisposable,你也不应该使用using语句。相反,这样做:

public class ApiShell : IApiShell
{
    _IDisposable _webApp;

    public void Start()
    {
        _webApp = WebApp.Start<Startup>("http://localhost:9090");
        Console.WriteLine($"Web server running at 'http://localhost:9090'");
    }

    public void Stop()
    {
        _webApp.Dispose();
    }
}

public class HostService
{
    public void Start()
    {
        IoC.Container.Resolve<IApiShell>().Start();  //start web app
    }

    public void Stop()
    {
        IoC.Container.Resolve<IApiShell>().Stop();  //stop web app
    }
}

您尚未显示您的依赖项注册,但请确保将IApiShell注册为单例,以便您启动/停止相同的实例。

请注意,如果这是传统的控制台应用程序而不是Windows服务,您可以这样做:

using (WebApp.Start<Startup>("http://localhost:9090"))
{
    Console.WriteLine($"Web server running at 'http://localhost:9090'");
    Console.WriteLine("Press any key to exit.");
    Console.ReadKey(true);
}

ReadKey方法将使using语句保持活动状态,从而防止Web应用程序被处置。

© www.soinside.com 2019 - 2024. All rights reserved.