我已经面对一个棘手的问题三天了。我有一个部署到IIS 8.5的WCF Web api(.svc服务文件)。应用程序正常工作,然后突然,在我更改了代码中的其他一些小问题之后,出现了这个问题:我可以从服务器内部连接到应用程序(使用localhost)。我可以使用服务器IP地址从外部连接。但我无论如何都不能通过使用服务器主机名从外部连接。通过下面的例子可以最好地理解这个问题:
注意:该应用程序是主网站内的IIS应用程序。服务的URI是http://myhostname/api/servicos.svc
我搜索了很多网站和论坛,但没有用。
我的web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<customErrors mode="Off" />
</system.web>
<connectionStrings>
<!-- My connection string goes here -->
</connectionStrings>
<system.serviceModel>
<services>
<service name="ServicoWeb.servico" behaviorConfiguration="Wcf_Behavior">
<endpoint name="" binding="webHttpBinding" contract="ServicoWeb.IServico" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp automaticFormatSelectionEnabled="true" defaultBodyStyle="Bare" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Wcf_Behavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="removeSvcDaUrl" type="ServicoWeb.Validacao.UrlCustomizacao, ServicoWeb" />
</modules>
<directoryBrowse enabled="true" />
<rewrite>
<rules>
<remove name="WordPress: https://myhostname.com" />
</rules>
</rewrite>
<handlers accessPolicy="Read, Execute, Script" />
<security>
<requestFiltering>
<verbs>
<add verb="*" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
</configuration>
尝试从外部(通过主机名)访问API时出现的错误是:
&#39; / Api&#39;中的服务器错误应用
无法找到资源。
描述:HTTP 404.您正在寻找的资源(或其中一个 依赖项)可能已被删除,其名称已更改,或者是 暂时不可用。请查看以下网址并制作 确保它拼写正确。
请求的网址:/Api/servico.svc/asos/csv/09655055000104
版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET版本:4.6.1069.1
你知道我该怎么办才能修复这个错误吗?
编辑:还有一个信息:IIS中同一网站内的其他应用程序工作正常!甚至还有其他使用C#编写的web apis,就像这里的一样,它们都能正常工作。
编辑2:另一件重要的事情是,我可以访问服务路径,直到服务本身(servico.svc)。因此,例如,当我尝试访问&#34; http://myhostname.com/api/servico.svc?wsdl&#34;我成功获得了服务的元数据。因此,只有当我尝试访问服务本身时,我才会收到上述错误。
答案 0 :(得分:0)
有一个名为host file的文件。当您尝试请求DN窗口查看该文件。 C:\WINDOWS\System32\drivers\etc
内的文件有主机文件。在主机文件中添加如下所示(使用管理员模式)。
server_ip_address myhostname.com
答案 1 :(得分:0)
我终于解决了!对于那些在没有成功的情况下努力解决这个问题的人:亚马逊EC2的负载平衡是导致我烦恼的原因。
发生了Load Balance设置为过滤所有请求并使用传输层SSL安全协议(HTTPS)将它们发送到服务器计算机。因此,如果我要求http://myserver.com/servico,亚马逊负载均衡会在内部重定向到https://machine-n/servico,其中&#39; n&#39;是使用的机器(在我的情况下,我有两台机器)。
因此,在WCF内部导致我的问题是:我的web.config不允许该服务接受HTTPS请求。一旦我解决了这个问题,一切正常。
它还解释了为什么当我请求使用HTTP直接使用机器的IP地址时一切正常:负载平衡在这种情况下没有任何作用,过滤请求并使用HTTPS重定向。
所以,这里我们有web.config,现在允许HTTPS请求:
<?xml version="1.0" encoding="UTF-8"?>
...
<system.serviceModel>
<services>
<service name="ServicoWeb.servico" behaviorConfiguration="Wcf_Behavior">
<endpoint name="" binding="webHttpBinding" contract="IServico" bindingConfiguration="webHttpTransportSecurity" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webHttpTransportSecurity">
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp automaticFormatSelectionEnabled="true" defaultBodyStyle="Bare" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Wcf_Behavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
...
答案 2 :(得分:0)
在我的情况下,事情有所帮助:
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
443
是否已打开并正常工作。