代码改变世界

(原创)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