对 C# Web 服务中 WSDL 文件中的主机名的使用感到困惑
我已经用 C# 创建了一个 WCF Web 服务,部署在 Windows 服务 EXE 中,它基本上按照我想要的方式工作。我以自托管方式使用它(不在 IIS 中)。
为了使 WSDL 文件可供调用 Java Web 服务使用,我将 ServiceMetadataBehavior 添加到主机创建中。即:
ServiceHost host = new ServiceHost(typeof(MyService));
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
这一切都工作正常,直到我将服务移动到具有不同主机名的另一台服务器。当我连接到 WSDL (http://prod-server:55000/MyService?wsdl) 时,我看到开发服务器的主机名硬编码在 WSDL 中。
下面是在浏览器中看到的 WSDL 片段:
<wsdl:definitions name="MyService" targetNamespace="http://tempuri.org/">
<wsdl:import namespace="MyProject.ServiceContracts" location="http://dev-server:55000/MyService?wsdl=wsdl0"/>
<wsdl:types/>
我已经检查了项目中的所有 C# 代码,并且开发服务器名称没有在任何地方进行硬编码。
在 App.config 文件中,我定义了以下内容:
<system.serviceModel>
<services>
<service name="MyService">
<endpoint address="http://localhost:55000/MyService" binding="basicHttpBinding"
bindingConfiguration="" contract="MyProject.ServiceContracts.IMyInterface" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:55000/MyService" />
</baseAddresses>
</host>
</service>
</services>
我预计这会导致本地主机计算机名称被替换,但它仍然保留为最初创建/部署服务的开发框名称。我错了吗?
我还研究了显式指定 WSDL 文件路径的可能性,但从我可以推断的情况来看,只有在 IIS 上托管服务时才能做到这一点。
最后,纯粹出于好奇,我想知道是否实际创建了一个实际的 WSDL 文件(我的意思是磁盘上的物理文件),或者它是随每个请求动态呈现的?
I have created a WCF web service in C# deployed in a Windows Service EXE which is largely working the way I want. I am using it in a self-hosted manner (not within IIS).
In order to make a WSDL file available to the calling Java webservice, I added ServiceMetadataBehavior to the host creation. i.e:
ServiceHost host = new ServiceHost(typeof(MyService));
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
This all worked fine until I moved my service to another server with a different host name. When I connect to the WSDL (http://prod-server:55000/MyService?wsdl), I see that the host name of the development server is hard coded in the WSDL.
Here is a snippet of the WSDL as seen in a browser:
<wsdl:definitions name="MyService" targetNamespace="http://tempuri.org/">
<wsdl:import namespace="MyProject.ServiceContracts" location="http://dev-server:55000/MyService?wsdl=wsdl0"/>
<wsdl:types/>
I have checked all of the C# code in the project, and the development server name is not hard coded anywhere.
In the App.config file, I have the following defined:
<system.serviceModel>
<services>
<service name="MyService">
<endpoint address="http://localhost:55000/MyService" binding="basicHttpBinding"
bindingConfiguration="" contract="MyProject.ServiceContracts.IMyInterface" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:55000/MyService" />
</baseAddresses>
</host>
</service>
</services>
I would expect that this would result in the localhost machine name being substituted, but it persists as the development box name on which the service was originally created / deployed. Am I mistaken?
I also looked into the possibility of explicitly specifying a path to my WSDL file, but from what I can deduce, this can only be done if hosting the service on IIS.
Lastly and purely out of curiosity, I wonder if an actual WSDL file actually gets created (a physical file on disk I mean) or is it dynamically rendered with each request?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它是动态创建的,不是每次调用 IIRC,而是在第一次向元数据端点请求时创建。我不确定为什么您会在非 DEV 计算机上看到您的 DEV 服务器名称,但是,因为您仅在端点地址中指定 localhost,所以它将使用服务器的主网络地址来解析 DNS。您可能需要考虑添加
useRequestHeadersForMetadataAddress
更改您的配置的行为,以便实际使用访问服务的 DNS。It is created dynamically, not every call IIRC, but on first request to the metadata endpoint. I'm not sure why your seeing your DEV server name on the non-DEV machine, but, because you're specifying localhost only in your endpoint address it's going to resolve DNS using the primary network address for the server. You may want to consider adding the
useRequestHeadersForMetadataAddress
behavior to your config so that the DNS with which the service is accessed is actually used instead.使用 WCF,WSDL 是动态生成的。
当我需要将 WSDL 作为文件发送给某人时,我在 WCF 3/3.5 服务上多次遇到此问题。通常我所做的就是保存文件(通常有 3 个,一个用于服务的 wsdl,一个用于您的类型的 xsd,以及一个用于 .net 类型的 xsd,但您的情况可能会有所不同),然后手动更新 wsdl 导入以引用相对于 wsdl 文件的其他两个文件,然后发送所有三个文件。
wsdl:service
、wsdl:port
和soap:address
仍将引用开发服务器,但大多数 ws 客户端库都会考虑到这一点允许开发人员配置端点。With WCF the WSDL is dynamically generated.
I have had this problem a number of times on a WCF 3/3.5 service when I needed to send a WSDL to someone as a file. Typically what I do is save the files (typically there are 3, a wsdl for the service, an xsd for your types, and an xsd for the .net types, but your mileage may vary), then manually update the wsdl imports to reference the other two files relative to the wsdl file, then send all three files.
The
wsdl:service
,wsdl:port
, andsoap:address
will still reference the dev server, but most ws client libraries account for this and allow the developer to configure the endpoint.