Silverlight有限支持WCF的binding问题
这是最近遇到的一个小问题。情况是这样的:
1.我们有一个网站,是用.NET Framework 3.5编写的,里面有一些WCF的服务。作为演示,我下面有一个范例服务
合约
using System.ServiceModel; namespace WebApplication1 { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. [ServiceContract] public interface IService1 { [OperationContract] void DoWork(); [OperationContract] string Helloworld(); } }
服务
namespace WebApplication1 { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together. public class Service1 : IService1 { public void DoWork() { } public string Helloworld() { return "hello,world"; } } }
2.我们需要在一个新的Silverlight应用程序中访问这些WCF服务,但是无论我们选择Silverlight的版本是3.0,还是4.0(注意,这不是.NET Framework的版本),都无法完成服务引用。
具体的症状就是,添加引用之后,Silverlight无法正确生成那个配置文件
会有两个警告
具体的信息是
Warning 2 Custom tool warning: No endpoints compatible with Silverlight 3 were found. The generated client class will not be usable unless endpoint information is provided via the constructor. d:\temp\WebApplication1\SilverlightApplication1\Service References\DataModel\Reference.svcmap 1 1 SilverlightApplication1
然后,我们去看那个生成的配置文件的话,会看到一片空白
这样的问题要怎么解决呢?我们首先要把问题找到,从上面的错误消息,它的意思应该是说,不支持目前提供的EndPoint。
那么,服务端到底使用了什么样的EndPoint呢
我们转到web应用程序中的web.config文件,可以看到如下的设置
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="WebApplication1.Service1Behavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="WebApplication1.Service1Behavior" name="WebApplication1.Service1"> <endpoint address="" binding="wsHttpBinding" contract="WebApplication1.IService1"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> </system.serviceModel>
也就是说,默认情况下,.NET Framework 3.5提供的WCF,是使用wsHttpBinding的。难道是Silverlight不支持这种EndPoint吗?
为了做测验,我们可以将其修改为相对简单的basicHttpBinding
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="WebApplication1.Service1Behavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="WebApplication1.Service1Behavior" name="WebApplication1.Service1"> <endpoint address="" binding="basicHttpBinding" contract="WebApplication1.IService1"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> </system.serviceModel>
然后,我们再去Silverlight中添加引用看看是否能解决问题
我们发现,这次成功了,ClientConfig中也正确生成了WCF的配置,并且通过如下的代码可以完成服务的调用
using System; using System.Windows; using System.Windows.Controls; using System.ServiceModel; namespace SilverlightApplication1 { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { var proxy = new DataModel.Service1Client(); proxy.Endpoint.Address = new EndpointAddress(new Uri(Application.Current.Host.Source, "../Service1.svc")); proxy.HelloworldCompleted += (o, a) => { MessageBox.Show(a.Result); }; proxy.HelloworldAsync(); } } }
好的,看起来问题是解决了,也就是说Silverlight只支持使用basicHttpBinding?如果我们非要改成wsHttpBinding ,行不行呢?
我尝试将clientconfig文件修改为
<configuration> <system.serviceModel> <client> <endpoint address="http://localhost:2514/Service1.svc" binding="wsHttpBinding" contract="DataModel.IService1" name="BasicHttpBinding_IService1" /> </client> </system.serviceModel> </configuration>
并且将服务端的web.config,也修改为
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="WebApplication1.Service1Behavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="WebApplication1.Service1Behavior" name="WebApplication1.Service1"> <endpoint address="" binding="wsHttpBinding" contract="WebApplication1.IService1"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> </system.serviceModel>
运行程序的结果是,会报告如下的错误
也就是说,确实不支持wsHttpBinding
关于这一点,有兴趣的朋友,也可以参考一下微软官方的文档说明
http://msdn.microsoft.com/en-us/library/cc896571(v=VS.95).aspx
【又及】
在Silverlight中,最简单易用的服务是RIA Service,关于这一点,我已经写过很多文章介绍。
那么,RIA Service是使用什么binding呢?
请参考下面这篇文章
http://weblogs.asp.net/fredriknormen/archive/2009/11/27/wcf-ria-services-binding-deep-dive.aspx
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
2009-06-19 使用架构(XSD)验证XML文件
2009-06-19 XSLT几种应用场景
2009-06-19 如何在XSLT样式表中声明命名空间
2009-06-19 视图的架构刷新和绑定
2009-06-19 浏览器的比较(IE和Chrome)
2009-06-19 LINQ TO XML之判断不存在行则插入
2009-06-19 由_vti目录想到的