初用WCF的朋友可能会遇到这样的问题,就是在使用svcutil.exe生成proxy和config的时候,或者利用add service reference添加引用的时候,部署的WCF服务到底它的metadata是什么。或者换句话说,svcutil的URL参数,以及添加服务引用时候的那个Address,到底应该填什么。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Description; namespace Nocturne.Learning.WcfAddressDemo { class Program { staticvoid Main(string[] args) { Uri baseAddress=new Uri("http://localhost:8009/MyService"); ServiceHost host =new ServiceHost(typeof(CalculatorService), baseAddress); ServiceMetadataBehavior smb =new ServiceMetadataBehavior() { HttpGetEnabled =true }; host.Description.Behaviors.Add(smb); host.AddServiceEndpoint(typeof(ICalculatorService), new WSHttpBinding(), baseAddress); host.Open(); Console.WriteLine("The service is ready."); Console.WriteLine("Press <ENTER> to terminate service."); Console.WriteLine(); Console.ReadLine(); } } }
D:\Program\temp>svcutil http://localhost:8009/MyService /language:cs /out:Proxy.cs /config:app.config
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.2152]
Copyright (c) Microsoft Corporation. All rights reserved.
Attempting to download metadata from 'http://localhost:8009/MyService' using WS-Metadata Exchange or DISCO.
Generating files...
D:\Program\temp\Proxy.cs
D:\Program\temp\app.config
using System; using System.ServiceModel; using System.ServiceModel.Description; namespace Nocturne.Learning.WcfAddressDemo { class Program { staticvoid Main(string[] args) { Uri baseAddress =new Uri("net.tcp://localhost:8009/MyService"); ServiceHost host =new ServiceHost(typeof(CalculatorService), baseAddress); ServiceMetadataBehavior smb =new ServiceMetadataBehavior(); host.Description.Behaviors.Add(smb); host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex"); host.AddServiceEndpoint(typeof(ICalculatorService), new NetTcpBinding(), baseAddress); host.Open(); Console.WriteLine("The service is ready."); Console.WriteLine("Press <ENTER> to terminate service."); Console.WriteLine(); Console.ReadLine(); } } }
与前面建立WSHttpBinding的代码有两个不同的地方。首先是smb里取消了HttpGetEnabled=true的属性设置,这是由于我们的基地址不是HTTP地址,会引发异常,错误信息是:The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the HttpGetUrl property is a relative address, but there is no http base address. Either supply an http base address or set HttpGetUrl to an absolute address。第二点就是最关键的元数据地址,添加了一个MexTcpBinding绑定类型的endpoint,它就承担为整个service对外提供元数据的任务。元数据的地址就是在基址后面加了“mex”的形式,在这里就是net.tcp://localhost:8009/MyService/mex。在实际应用中,这个“mex”可以省略,即只用net.tcp://localhost:8009/MyService,系统会自动去寻找mex,而如果在前面建立endpoint的时候,用的是其它的名称(比如mex1),那就不能省略了。建议使用完整路径。
D:\Program\temp>svcutil net.tcp://localhost:8009/MyService/mex /language:cs /out:Proxy.cs /config:app.config
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.2152]
Copyright (c) Microsoft Corporation. All rights reserved.
Attempting to download metadata from 'net.tcp://localhost:8009/MyService' using WS-Metadata Exchange. This URL does not support DISCO.
Generating files...
D:\Program\temp\Proxy.cs
D:\Program\temp\app.config
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端