WCF WebService/IIS托管&;防火墙后的配置问题

WCF WebService/IIS托管&;防火墙后的配置问题,wcf,web-services,iis,.net-3.5,configuration,Wcf,Web Services,Iis,.net 3.5,Configuration,我有一个简单的WCF Web服务。它托管在我们生产域中默认网站下的IIS上。(本地地址:10.10.20.100) 默认情况下,此默认网站是为端口80上的“所有未分配”IP设置的:但是,我注意到这导致WCF服务使用服务器本地DNS名称生成其WSDL。i、 e.wsdl中的所有URI都是 http://myserver.subdomain.domain.com/.../... 这不好,因为我需要将此服务公开给不了解生产环境内部DNS的站点。而且这个特定的服务器没有外部DNS名称。只是一个外部IP

我有一个简单的WCF Web服务。它托管在我们生产域中默认网站下的IIS上。(本地地址:10.10.20.100)

默认情况下,此默认网站是为端口80上的“所有未分配”IP设置的:但是,我注意到这导致WCF服务使用服务器本地DNS名称生成其WSDL。i、 e.wsdl中的所有URI都是

http://myserver.subdomain.domain.com/.../...
这不好,因为我需要将此服务公开给不了解生产环境内部DNS的站点。而且这个特定的服务器没有外部DNS名称。只是一个外部IP地址

我成功地将IIS中的设置从“所有未分配”->“10.10.20.100”更改为“10.10.20.100”

这将导致服务使用URI生成其WSDL

http://10.10.20.100/.../...
这对于子域内和其他子域上的其他机器来说是很好的,但就是在这里我被卡住了。服务器外部IP地址(1.2.3.4)通过一些NAT/PAT转换进行映射,因此不会在服务器IP设置中明确设置(即,它不会显示在IP配置下)

因此,如果我将IIS默认网站IP地址从“All Unassigned”->“1.2.3.4”更改为内部地址,那么WCF服务将返回

请求错误(主机名无效)

如果我在内部IP地址上保留IIS配置,并尝试通过我获得的外部IP地址访问服务

No protocol binding matches the given address 
'http://1.2.3.4/TestService/Service.svc'. Protocol bindings are 
configured at the Site level in IIS or WAS configuration
有没有办法让IIS/WCF生成它的WSDL URI,并使用服务器上未显式配置的外部IP地址


在我把WCF服务扔出窗外之前,请有人帮帮我。

我也许能阻止忍者暴力。。。如果我理解你的问题。。。 您可以在web.config中手动指定服务应使用的完整地址,而不是让ServiceHost为您计算。您必须设置服务的基址:

 <service behaviorConfiguration="Behaviour1" name="Api.Poll">
    <endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="soapBinding"
      contract="Api.IPoll" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://www.mydomain.com/Api" />
        <add baseAddress="http://10.10.20.30/Api" />
      </baseAddresses>
    </host>
  </service>
最后,构建ServiceHostFactory类后,必须通过编辑.svc文件中的标记将其连接到服务:

<%@ ServiceHost Language="C#" Debug="true" Service="Api.Poll" Factory="Api.ServiceHostFactory" CodeBehind="Poll.svc.cs" %>

它必须是IP地址而不是FQDN吗?通过交换到FQDN并在站点的主机头中设置该FQDN,然后通过

cscript //nologo %systemdrive%\inetpub\adminscripts\adsutil.vbs set W3SVC/1/ServerBindings ":80:hostname.example.com"

然后,回收应用程序池将在生成的WSDL中生成该主机名。您可以从中获得好处-您可以设置一个内部DNS,将FQDN解析为内部IP,以及一个外部DNS,将其解析为您的防火墙IP,然后相同的系统将在不做任何更改的情况下工作。

这是因为您没有设置主机头。这似乎是一个非常常见的问题,我一直都会遇到。它生成的URI没有配置,它通过检查站点的主机头来查找正确的地址。即使它位于虚拟目录中,您也需要转到父目录(在您的情况下为默认目录),并添加主机头


如果您不知道如何执行此操作,请告诉我。

以下是如何更改IIS7中的标题。如果有帮助的话,也可以使用我的web.config


尽管这是一个旧线程,但它实际上帮助我将一个项目从VS Web Developer Express迁移到了MonoDevelop,其中包括一个WCF服务

web应用程序使用以下URL请求WCF服务定义的JavaScript接口:,这给了我一个错误:没有与给定地址匹配的协议绑定

受这个线程的启发,我能够解决这个问题,因为使用localhost而不是127.0.0.1访问服务是可行的!通过对的请求,我得到了JavaScript接口

实际上,我的应用程序没有使用绝对URL来包含JavaScript接口,但是默认情况下,当从MonoDevelop启动应用程序时,它将使用127.0.0.1访问应用程序,因此从服务中调用包含JavaScript失败


它仍然不是完美的,因为我无法使用localhost而不是127.0.0.1从MonoDevelop启动应用程序,因为XSP的配置只允许我指定IP地址,但至少我知道如何解决这个问题。

问题是,在更改端口或ip地址后,您应该重新启动您使用的应用程序池,因为在重新接收之前,它仍然保留旧信息。

在IIS下托管时,web.config的BaseAddress部分完全被忽略。有没有它没有关系。IIS根据虚拟目录配置计算出地址。隐马尔可夫模型。。。我以前在IIS中使用过它,但这是一个不同的场景,有多个基址。我想知道您是否可以使用ServiceHostFactory以编程方式设置基址。见修改后的答案。为这个史蒂夫干杯。。。现在是格林威治标准时间晚上9点,所以当我回到办公室,明天再来找你时,我会试试这个。你能澄清一下我在哪里创建这个类吗。我只是把它放到App_代码文件夹中,然后让我的服务扩展它吗?是的,你可以把它放到App_代码部分,这样就行了。不过,还有最后一步要连接它,要做到这一点,您必须修改.svc文件的标记。我已经更新了答案,包括这个。这是一个好问题。为什么像这样的问题得不到支持票,而像“厌倦了编写GUI/业务应用程序,下一步该怎么做?”这样的问题在几分钟内得到4票?遗憾的是,我没有答案给你——我只能提供支持票+1.感谢迄今为止的答案
cscript //nologo %systemdrive%\inetpub\adminscripts\adsutil.vbs set W3SVC/1/ServerBindings ":80:hostname.example.com"
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />      
    <customErrors mode="Off"></customErrors>
  </system.web> 
  <system.serviceModel>
    <client/>
    <services>
      <service name="WcfService1.Service1"
behaviorConfiguration="MyServiceTypeBehaviors">
        <host>
        <baseAddresses>
          <add baseAddress="https://pws.sjukra.is/"/>        
        </baseAddresses>
        </host>
        <endpoint address="https://pws.sjukra.is/Service1.svc"
                  listenUri="/" 
        binding="wsHttpBinding"
        contract="WcfService1.IService1"
        bindingConfiguration="myBasicHttpBindingConfig"/>
        <endpoint contract="IMetadataExchange"
   binding="mexHttpsBinding"                   
   address="mex"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="myBasicHttpBindingConfig">
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="Windows" />
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceTypeBehaviors">
          <serviceMetadata httpsGetEnabled="true"/>
          <serviceDebug httpsHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
          <serviceCredentials type="System.ServiceModel.Description.ServiceCredentials">
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfService1.Service1,WcfService1"/>
            <serviceCertificate findValue="pws.sjukra.is" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
              <clientCertificate>
                  <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
              </clientCertificate>            
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>