简体   繁体   English

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

[英]Cannot see my controller in self hosted WebApi project

I created a self hosted web api app, to run as a Windows Service, using TopShelf, and Autofac for dependency injection. 我创建了一个自托管的Web api应用程序,使用TopShelf和Autofac作为依赖项注入作为Windows服务运行。

Here is my StartUp logic: 这是我的启动逻辑:

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

And I start the WebApp as follow: 然后按以下方式启动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 configuration: 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");
        });

My controller: 我的控制器:

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

I installed Swagger as well, but I can't reach my controller, using either of the following attempts: 我也安装了Swagger,但是使用以下任何一种尝试都无法访问控制器:

http://localhost:9090/api/Ping http:// localhost:9090 / api / Ping

http://localhost:9090/swagger http:// localhost:9090 / swagger

What am I missing? 我想念什么?

You can't just do this: 您不能只是这样做:

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

After the write line, there's no more statements left in the using, so the using will close, thus stopping the web app. 在写行之后,使用中没有其他语句,因此使用将关闭,从而停止了Web应用程序。 This is one of those cases where even though the result of WebApp.Start is an IDisposable , you shouldn't use a using statement. 在这种情况下,即使WebApp.Start的结果是IDisposable ,也不应使用using语句。 Instead, do this: 相反,请执行以下操作:

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
    }
}

You haven't shown your dependency registration, but make sure that IApiShell is registered as a singleton so you're starting/stopping the same instance. 您尚未显示依赖项注册,但是请确保IApiShell已注册为单例,以便您启动/停止同一实例。

Note, if this were a traditional console app instead of a Windows service, you could do this: 请注意,如果这是传统的控制台应用程序而不是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);
}

The ReadKey method would keep the using statement active and thus keep the web app from disposing. ReadKey方法将使using语句保持活动状态,从而防止Web应用程序被处置。

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

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