具有相对路径的Asp.net自托管WCF服务WSDL
我正在开发一个WCF应用程序,该应用程序将在此过程中部署到不同的服务器上,我不想每次部署时都记得更改app.config。起初,我的app.config serviceModel部分如下所示:具有相对路径的Asp.net自托管WCF服务WSDL,asp.net,wcf,wsdl,Asp.net,Wcf,Wsdl,我正在开发一个WCF应用程序,该应用程序将在此过程中部署到不同的服务器上,我不想每次部署时都记得更改app.config。起初,我的app.config serviceModel部分如下所示: <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="false" /> <behaviors> <serviceBehaviors>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
<behaviors>
<serviceBehaviors>
<behavior name="MyDefaultServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8888/MyService" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyDefaultServiceBehavior" name="MyService">
<endpoint address="net.tcp://localhost:9001/MyService" binding="netTcpBinding" contract="IMyService" name="NetTcpBinding_IMyService" />
</service>
</services>
ServiceHost host = new ServiceHost(typeof(WebApplication.TestService));
ServiceMetadataBehavior metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = new Uri(string.Format(
"http://{0}/WebApplication/TestService.svc",
Environment.MachineName));
host.Description.Behaviors.Add(metadataBehavior);
当我访问本地机器上运行的服务时,这在开发中运行良好。当我部署它时,WSDL包含仍然指向localhost的绝对路径:
<xsd:import schemaLocation=http://localhost:8888/MyService?xsd=xsd0 namespace="http://tempuri.org/" />
因此,我可以在app.config中更改httpGetUrl,如下所示:
<serviceMetadata httpGetEnabled="true" httpGetUrl=http://devserver1:8888/MyService />
现在wsdl在该服务器上正常工作。问题是我必须在每个部署的app.config中手动设置地址
有没有办法做到这一点:1.wsdl是否已经包含了所有内容,因此没有导入?
或
2.在wsdl导入语句中使用相对路径?
或任何其他建议将不胜感激。如果不是因为这个wsdl问题,我有两个自动部署到的开发服务器 因为这只是为了生成代理,我想我可以自己生成代理并分发它,但我宁愿让用户自己生成代理 谢谢!
Daniel您可以通过编程方式设置的值,并将其设置为包含承载服务的服务器的机器名的绝对地址。生成的WSDL中的导入语句也将使用服务器的机器名 如果您的WCF主机是为您创建的(例如,您在IIS下托管),则您将需要创建一个自定义主机来访问。例如:
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Description;
namespace WebApplication
{
public class TestServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType,
Uri[] baseAddresses)
{
ServiceHost host = base.CreateServiceHost(serviceType,
baseAddresses);
ServiceMetadataBehavior metadataBehavior =
new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = new Uri(string.Format(
"http://{0}/WebApplication/TestService.svc",
Environment.MachineName));
host.Description.Behaviors.Add(metadataBehavior);
return host;
}
}
}
然后在服务的.svc文件中指定此工厂:
<%@ ServiceHost Language="C#"
Service="WebApplication.TestService"
CodeBehind="TestService.svc.cs"
Factory="WebApplication.TestServiceHostFactory" %>
丹尼尔·理查森(Daniel Richardson)在上面给出的答案是一个很好的答案,我认为对大多数人来说,这将是首选的解决方案。然而,由于我们的网络布局和需要访问服务器的人数很少,我正在做一些不同的事情 我已将app.config更改为包含“myServiceServer”的httpGetUrl:
要使用我的服务,必须先添加一个主机文件条目,将“myServiceServer”映射到正确的IP地址。这对我们的问题很有效,因为IP地址无法从任何通用机器名或IP地址解析。这是因为分离的网络仅由VPN连接,并且有某种NAT在进行。显然,WCF中内置了一个非常隐蔽的选项,支持使用与传入请求相同的主机名,这通常是正确的。(我认为它不是默认设置的唯一原因是为了向后兼容,尽管如果他们将其设置为默认设置可能会更好。) 在我找到这个特殊的宝石之前,我花了很多时间搜寻和拉扯头发(尽管现在我知道了这个神奇的单词,我发现它来自于我的一次类似的旅行) 要启用它,请在添加
ServiceMetadataBehavior
的同一位置添加以下代码:
host.Description.Behaviors.Remove();
host.Description.Behaviors.Add(新的UseRequestHeadersForMetadataAddressBehavior());
我就是这么做的。对我来说,更大的问题是不是每个人都可以使用机器名访问服务器。对一些人来说,这甚至不能解决问题。你的解决方案很好地回答了我的问题,但不幸的是,我把问题简化得太多了,并没有解决我的问题。有关解决方案,请参阅其他注释。
<serviceMetadata httpGetEnabled="true" httpGetUrl=http://myServiceServer:8888/MyService />