在Windows服务中使用OWIN托管Web API

时间:2014-02-07 17:40:14

标签: asp.net-web-api owin

我使用OWIN(在Windows服务中)自我托管Web API。据我所知,这足以让HTTP请求进入Windows服务。我能够在本地(来自同一台机器)点击WebAPI URL(http://localhost/users),但不能从其他机器点击。我正在使用端口80, IIS已停止。其他网站(在IIS中,在端口80上托管)在IIS运行时工作正常。

//在Windows服务中:

public partial class Service1 : ServiceBase
{
    ...
    ...

    protected override void OnStart(string[] args)
    {
        Console.WriteLine("Starting service...");
        string baseAddress = "http://localhost:80/";
        WebApp.Start<Startup>(baseAddress);  //This is OWIN stuff.
    }
    ...
    ...
}

public class Startup
{
    // This code configures Web API. The Startup class is specified as a type
    // parameter in the WebApp.Start method.
    public void Configuration(IAppBuilder appBuilder)
    {
        // Configure Web API for self-host.
        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        appBuilder.UseWebApi(config);
    }
}

我是否需要做更多工作才能让其他机器正常工作? (我感觉传入的http请求没有被转发到Windows服务,只能转发到IIS。当你点击本地时,它可能不会通过侦听http请求的操作系统模块。只是一个猜测。)

6 个答案:

答案 0 :(得分:52)

您的计算机的防火墙可能会阻止传入的请求。你可以这样做:

您可以运行wf.msc命令打开具有高级安全性的Windows防火墙,并为TCP端口80添加新的入站规则。

(您应该注意到一些以World Wide Web Services...开头的入站规则。这些是针对IIS的。我不确定启用这些规则是否足以让您的Windows服务接收请求...您可以尝试看看之前是否按照建议工作,你可以创建一个新的入站规则..)

<强>更新
根据您的评论,可能是因为您的Url注册,您无法点击该服务。以下是使用HttpListener注册多个URL的一些示例。

StartOptions options = new StartOptions();
options.Urls.Add("http://localhost:9095");
options.Urls.Add("http://127.0.0.1:9095");
options.Urls.Add(string.Format("http://{0}:9095", Environment.MachineName));

using (WebApp.Start<Program>(options))
{

您可以在以下链接中阅读有关网址注册的更多信息:
http://technet.microsoft.com/en-us/library/bb630429.aspx
http://technet.microsoft.com/en-us/library/bb677364.aspx

答案 1 :(得分:17)

有两件事会阻止你使用与#34; localhost&#34;在Owin服务:

  1. 应用程序需要以管理员身份运行,以便打开一个具有不同主机名的端口作为&#34; localhost&#34;。您可以通过使用管理员权限运行应用程序或使用以下命令为给定端口添加例外来解决此问题:netsh http add urlacl url=http://*:9000/ user=<your user>
  2. Windows防火墙可能会阻止来自其他计算机的流量。在我的情况下,防火墙没有阻止本地流量(我可以访问http://localhost:9000http://127.0.0.1:9000http://192.168.1.193:9000 - 这是我在同一台计算机上的本地IP地址,但需要添加端口允许从另一台计算机访问此服务的防火墙例外)

答案 2 :(得分:6)

我遇到了类似的问题。以下解决方案对我有用。

StartOptions options = new StartOptions();
options.Urls.Add("http://localhost:9095");
options.Urls.Add("http://127.0.0.1:9095");
options.Urls.Add(string.Format("http://{0}:9095", Environment.MachineName));

using (WebApp.Start<Program>(options))
{
    ...
}

答案 3 :(得分:4)

这实际上是一个简单的疏忽我也绊倒了:如果你只听取localhost,127.0.0.1等的请求 - 没有人会看到它,因为只有你(自己)才能理解你作为那个目标。在我的机器上我是localhost,如果我在任何端口上查询你的IP,那么该服务将看到get http://your_ip:80,而不是localhost。您所要做的就是在“http:// *:{0}”上提供服务,这样您就可以通过onStart()传递该端口。

答案 4 :(得分:1)

类似的问题。我编写了一个ServiceStack服务,并使用AppSelfHostBase实现将其托管在Windows服务中。注意:这是作为Net Core应用程序编写的,可编译为控制台应用程序,但通过PeterKottas.DotNetCore.WindowsService(可通过NuGet获得)的魔力可以安装为Windows服务。

我将baseAddress设置为http://*.8088/并将其传递给我的AppSelfHostBase实现,但我只能从安装它的同一台机器上访问该服务,而不是通过尝试打开浏览器中的元数据页面(http://[machine]:8088/api/metadata)。解决方案是将我的控制台应用程序.exe文件添加到安装它的服务器上的Windows防火墙中允许的应用程序列表中。只需转到服务器控制面板中的防火墙“允许的应用程序”对话框,单击“允许其他应用程序...”按钮,然后导航到Windows服务可执行文件:

Windows Firewall Allowed App dialog

答案 5 :(得分:0)

最终对我有用的是这个价值:

StartOptions options = new StartOptions();
options.Urls.Add("http://*:9095");

using (WebApp.Start<Program>(options))
{
    ...
}

请注意,添加此内容后,您只能使用Admin模式在Visual Studio中运行该应用程序,并且该应用程序的发行版也需要在Admin模式下运行。