如何将WSDL URL从内部机器名称更改为公共名称?

42

我有一个简单的服务,我部署在Azure上。它可以通过以下方式访问:

http://xxxxxxxxxxxxxxxxxxxxxxx.cloudapp.net/MyTestService.svc

WSDL的URL使用内部机器名称而不是公共DNS:

svcutil.exe http://rd001520d328923a/MyTestService.svc?wsdl

显然,这样做是无法从机器外部访问WSDL的。

我知道有一些可以更改的东西,如果您在IIS中运行此服务,或者您知道服务的URL。例如,更改<serviceMetadata>配置以指定httpGetUrl属性,但这样做不起作用,因为我必须包括绝对URL。使用相对URL,在内部仍将使用机器名称。真正的问题在于WSDL包含带有机器名称的URL引用,因此它变得无用。

有两个次优的解决方法:

  • 有人建议我可以获取WSDL,编辑它以修复URL,然后上传它,以便从不同的URL访问。

  • 我发现了一个早期2010年的热修复程序,但肯定有更好的方法。

如何解决这个问题,以便使用公共面向DNS而不是机器名称?

3个回答

69

好的。我已经研究了这个问题将近一周。我终于找到了答案,因为它不容易得到,所以我希望这篇文章可以被索引,为其他人节省时间。

基本上,这种总体行为是WCF 3.0/3.5已知的问题,他们发布了一个热修复补丁。您可以在这里了解更多信息:FIX: URIs in a WCF WSDL document refer to inaccessible internal instances instead of to the load balancer...

在我的研究中,我遇到过几次这种情况,但从未想过第二次,主要是因为我不知道如何将热修复程序部署到 Azure 中。

幸运的是,MSDN 论坛上的 Microsoft 主持人指出,这在 .net 4.0 中已经得到了修复。这意味着“解决方案”建议仍然适用于上面的 KB 文章,唯一的例外是不需要应用任何热修复程序。那么解决方案是什么?简单地将以下内容添加到配置文件中:

<serviceBehaviors>
   <behavior name="<name>">
     <!-- Other options would go here -->
     <useRequestHeadersForMetadataAddress>
       <defaultPorts> <!-- Use your own port numbers -->
          <add scheme="http" port="81" />
          <add scheme="https" port="444" />
        </defaultPorts>
      </useRequestHeadersForMetadataAddress>
   </behavior>
</serviceBehaviors>

就是这样了。 如果当时清楚地表明这个问题已经被解决了,这个搜索本来应该简单得多。也许我没有找得够仔细。


1
这对我们来说非常完美,我们在wsdl中获得了localhost引用,现在我们可以获取正确的外部地址。(.NET 4.0,自托管wcf) - David Cumps
1
非常感谢,这节省了我很多时间。 - user1274668
感谢您挽救了我的工作!但是给出的网址已经失效了。 - KumarHarsh

24

这篇博客文章“使用请求头传递元数据地址”Victor答案相似,但解释了默认端口是可选的,并可以省略:

<system.serviceModel>
  <behaviors>
       <serviceBehaviors>
          <behavior>
            <useRequestHeadersForMetadataAddress/>
          </behavior>
        </serviceBehaviors>
  </behaviors>
</system.serviceModel>

它还展示了如何在代码中启用该行为。

sh.Description.Behaviors.Add(new UseRequestHeadersForMetadataAddressBehavior());

2
太棒了!谢谢你! - Jeremy
我不得不像@Victor的答案中那样提及默认端口。不知道为什么?也许是因为我的WCF应用程序被托管为子应用程序。 - KumarHarsh

0
你是为了发布WSDL而生成它,还是只是想在另一个项目中添加引用?
如果是后者,我的建议是使用WCF ChannelFactory方法,而不是“添加服务引用”。我发现这样可以给我带来更一致可控的结果。

http://msdn.microsoft.com/en-us/library/ms734681.aspx

我必须声明,我没有在Azure上尝试过这个。


两者皆需。我们需要我们的合作伙伴进行消费。 - Victor
WSDL是否在正确的URL上工作? 我知道元数据页面没有正确显示它,但是为了让合作伙伴使用,您不会直接将WSDL路径交给他们吗?而不是发送到一个页面获取。 - Taylor Bird
生成的 WSDL 中 URL 不正确。因此,“解决方案”是手动抓取 WSDL,修改并上传到目录中,然后提供新路径。 - Victor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接