(原创)Silverlight远程调用WCF
2013-04-10 20:04 Keiven_LY 阅读(422) 评论(0) 编辑 收藏 举报2.1 跨域问题
就是WCF提供服务,Silverlight消费服务。如果WCF提供的address,比如是http:/localhost:8839/,而Silverlight运行的端口不一致,比如是http:/localhost:7777/,就不是在同一个域中,这时就出现跨域访问的问题。
解决方法:
在WCF服务的根目录下,创建一个clientaccesspolicy.xml文件,文件内容为:
<access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="*"> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
项目架构
注:这里创建的xml文件,要放在C:\Inetpub\wwwroot下,用于IIS发布。
只是加了这个文件还不行,还要将这个作为服务来提供。
第一种方案是,在原有的服务接口中增加该服务接口,及该服务的实现方法,尝试了这种方案,问题未得到解决;
第二种方案是,在服务器端新添加WCF服务,取名“PolicyRetriever.vb”,同时自动生成相应的接口,I PolicyRetriever.vb,如上图所示。
接口代码:
<OperationContract()> _ <WebGet(UriTemplate:="ClientAccessPolicy.xml")> _ Function ProvidePolicyFile() As System.ServiceModel.Channels.Message
注:这里用到WebGet的方法,要在IPolicyRetriever.vb中,添加引用:
Imports System.ServiceModel.Web
接口实现代码:
Public Function ProvidePolicyFile() As System.ServiceModel.Channels.Message Implements IPolicyRetriever.ProvidePolicyFile Dim filestream As FileStream = File.Open("C:\Inetpub\wwwroot\clientaccesspolicy.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite) '此处访问xml地址 Dim reader As XmlReader = XmlReader.Create(filestream) Dim result As System.ServiceModel.Channels.Message = Message.CreateMessage(MessageVersion.None, "", reader) Return result End Function
注:
因为用到FileStream,故要添加引用:
Imports System.IO
因为用到XmlReader,故要添加引用:
Imports System.Xml
因为用到Message,故要添加引用:
Imports System.ServiceModel.Channels
关键部分:
App.Config中,需要修改的地方是:
<behaviors>
<endpointBehaviors>
<behavior name="WebHttpNewBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<service behaviorConfiguration="Boolean_Server_Host_1.MP3_BroadServiceBehavior"
name="Boolean_Server_Host_1.MP3_BroadService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
contract="Boolean_Server_Host_1.IMP3_BroadService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://10.3.11.169:8731/MP3_BroadService/" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="Boolean_Server_Host_1.PolicyRetrieverBehavior"
name="Boolean_Server_Host_1.PolicyRetriever">
<endpoint address="" behaviorConfiguration="WebHttpNewBehavior" binding="webHttpBinding" contract="Boolean_Server_Host_1.IPolicyRetriever">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://10.3.11.169:8731/" />
</baseAddresses>
</host>
</service>
注:上述红色部分是需要添加及修改的地方!
注:开启服务按钮事件中,也要将该服务开启
至此,当服务开启后,在浏览器中输入http://10.3.11.169:8731/clientaccesspolicy.xml
若能看到该xml的内容,就说明跨域问题得到解决。
2.2 以开启和关闭紧急广播为类
第一步:在MainPage.xml中添加两个Button,分别为“开启紧急广播”和“关闭紧急广播”,代码如下:
<Grid x:Name="LayoutRoot" Background=" #46461F"> <Button x:Name="Button_1" Content="开启紧急广播" FontSize=" 24" Foreground="#FF0046FF" Click="Button_1_Click" Margin="66,240,0,200" Width="150" Height="40" RenderTransformOrigin="-0.94,-2.2" HorizontalAlignment="Left" d:LayoutOverrides="Width" > <Button.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="White" Offset="1"/> <GradientStop Color="#FF3D3D3D" Offset="0.241"/> </LinearGradientBrush> </Button.Background> </Button> <Button x:Name="Button_2" Content="关闭紧急广播" FontSize=" 24" Foreground="#FF0046FF" Click="Button_2_Click" Margin="66,328,0,112" Width="150" Height="40" RenderTransformOrigin="-0.94,-2.2" HorizontalAlignment="Left" d:LayoutOverrides="Width" > <Button.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="White" Offset="1"/> <GradientStop Color="#FF3D3D3D" Offset="0.241"/> </LinearGradientBrush> </Button.Background> </Button> </Grid>
第二步:添加服务引用
第三步:按钮的点击事件(关键)
'*****************************************开启紧急广播功能******************************' Private Sub Button_1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) AddHandler proxy.AlarmSpeechCompleted, AddressOf AlarmSpeech_Completed '事件捆绑 proxy.AlarmSpeechAsync() End Sub Private Sub AlarmSpeech_Completed(ByVal sender As Object, ByVal e As MP3_Broad_Service.AlarmSpeechCompletedEventArgs) '捆绑事件 MessageBox.Show(e.Result) End Sub '*****************************************关闭紧急广播功能******************************' Private Sub Button_2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) AddHandler proxy.AlarmSpeech_GuanCompleted, AddressOf AlarmSpeech_Guan_Completed'事件捆绑 proxy.AlarmSpeech_GuanAsync() End Sub Private Sub AlarmSpeech_Guan_Completed(ByVal sender As Object, ByVal e As MP3_Broad_Service.AlarmSpeech_GuanCompletedEventArgs) '捆绑事件 MessageBox.Show(e.Result) End Sub