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-pe.aspx

本文来自陈希章的博客,原文地址:http://www.cnblogs.com/chenxizhang/archive/2011/06/19/2084524.html


分享给朋友:
您可能感兴趣的文章:
随机阅读: