首語
本人在學習Silverlight 和 WCF的時候,各種問題層出不窮,在園子里面查閱大量的資料,尤其是Artech和Frank xu Lei 的WCF博文給我很大的幫助,在此衷心感謝兩位。本人不才,特寫下幾個Silverlight和WCF通信的例子與大家分享和交流,希望初學者少走些彎路,而專心於系統的業務層的開發,高手請繞行,但歡迎拍磚!:)
本系列是面向Silverlight和WCF交互初學者的,主要包括:
Silverlight 通過httpBinding方式訪問IIS 宿主WCF
Silverlight通過netTcpBinding方式訪問IIS 宿主WCF
Silverlight通過netTcpBinding方式訪問IIS 宿主WCF(全雙工)
Silverlight通過httpBinding方式訪問控制台宿主WCF
Silverlight通過netTcpBinding方式訪問控制台宿主WCF
Silverlight通過httpBiding方式訪問IIS宿主WCF是我們在Silverlight與WCF通信中最為常見的,也是用的最多的,我們用個很簡單的例子進行演示。
項目結構:

項目目結構簡單說明:
| 程序集名稱 | 需添加的引用 | 簡要說明 |
| LxContracts | System.Runtime.Serialization System.ServiceModel | 用於存放操作契約與數據契約 |
| LxServices | LxContracts[項目] | 服務,操作契約的實現 |
| WcfHost.web | LxContracts[項目] 和LxServices[項目] | 利用Svc文件發布服務的站點 |
| SilverlightDemo | Silverlight程序,調用WCF服務 |
注意:建立Silverlight程序的時候,不需要承載網站,建立一個單一的Silverlight程序即可,這樣做的原因是,把Silverlight和WCF服務不放到同一個站點下面,是為了演示跨域的問題。
代碼實現:
類庫LxContracts:(包括數據契約Student.cs和操作契約IStudent.cs)
Student.cs 代碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Runtime.Serialization; namespace LxContracts { [DataContract] public class Student { /// <summary> /// 學生編號 /// </summary> [DataMember] public int StuId { get; set; } /// <summary> /// 學生姓名 /// </summary> [DataMember] public string StuName { get; set; } /// <summary> /// 所在班級 /// </summary> [DataMember] public string ClassName { get; set; } /// <summary> /// 聯系電話 /// </summary> [DataMember] public string TelPhoneNum { get; set; } } }
IStudent.cs 代碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; using System.ServiceModel; namespace LxContracts { [ServiceContract] public interface IStudent { [OperationContract] List<Student> GetStudent(); } }
類庫LxServices:( 改類庫包括一個模仿獲取數據庫集合類StudentList.cs和服務類StudentService.cs)
StudentList.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using LxContracts; namespace LxServices { public class StudentList:List<Student> { public StudentList() { this.Add(new Student() { StuId = 1, StuName = "小明", ClassName = "計算機一班", TelPhoneNum = "123456" }); this.Add(new Student() { StuId = 2, StuName = "小紅", ClassName = "計算機二班", TelPhoneNum = "234567" }); this.Add(new Student() { StuId = 2, StuName = "小蘭", ClassName = "計算機三班", TelPhoneNum = "890123" }); } } }
StudentService 代碼
using System; using System.Collections.Generic; using System.Linq; using System.Text; using LxContracts; namespace LxServices { public class StudentService:IStudent { public List<Student> GetStudent() { //實際情況應該為從數據庫讀取 //本例手動生成一個StudentList StudentList ListStuent = new StudentList(); return ListStuent; } } }
站點WcfHost.web
站點WcfHost.web,這是一個Asp.net 空web應用程序。
1、右擊” WcfHost.web”—“添加”—“新建項”—“wcf服務”,命名為”StudentSrv.svc” 。如圖:

在項目中刪除”StudentSrv.svc.cs”文件和”IStudentSrv.cs”文件。右擊”StudentSrv.svc”文件,選擇”查看標記”,將代碼修改為:
<%@ ServiceHost Language="C#" Service="LxServices.StudentService" %>
2、修改webconfig 文件,代碼如下:
WebConfig
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="LxBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service name="LxServices.StudentService" behaviorConfiguration="LxBehavior"> <endpoint address="" binding="basicHttpBinding" contract="LxContracts.IStudent" /> </service> </services> <!--關閉 ASP.NET 兼容性模式--> <serviceHostingEnvironment aspNetCompatibilityEnabled="false"/> </system.serviceModel> </configuration>
注意:endpoint中的address 為空:因為svc文件的地址就是元數據發布的地址。
3、右擊”StudentSrv.svc”文件,在”瀏覽器中查看”,顯示如下圖,說明服務已經部署好了,我用的端口是 9090:

在Silverlight中進行調用:
Silverlight調用wcf很簡單,直接在”SilverlightDemo”中添加”服務引用即可”,Silverlight項目中會自動生成” ServiceReferences.ClientConfig”配置文件,當然也可以利用代碼的方式調用,但是我比較懶 :)。
1、為Silverlight程序添加WCF:
“右擊”—“SiverlightDemo”—“添加服務引用”—“輸入服務地址”(我的是http://localhost:9090/StudentSrv.svc)--點擊“前往”,就會找到服務,命名為“WCF.StudentSrv”后,點擊“確定”

2、在Silverlight中調用WCF:
MainPage.xaml中添加”DataGrid”控件,xaml代碼如下:
MainPage.xaml 代碼
<sdk:DataGrid x:Name="dgStudnet" Grid.Row="0" AutoGenerateColumns="False"> <sdk:DataGrid.Columns> <sdk:DataGridTextColumn Header="學生編號" Width="80" Binding="{Binding StuId}" /> <sdk:DataGridTextColumn Header="學生姓名" Width="100" Binding="{Binding StuName}" /> <sdk:DataGridTextColumn Header="所在班級" Width="120" Binding="{Binding ClassName}" /> <sdk:DataGridTextColumn Header="電話號碼" Width="100" Binding="{Binding TelPhoneNum}" /> </sdk:DataGrid.Columns> </sdk:DataGrid>
MainPage.cs 代碼
public partial class MainPage : UserControl { ObservableCollection<Student> listStudent; public MainPage() { InitializeComponent(); listStudent = new ObservableCollection<Student>(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { StudentClient proxyClient = new StudentClient(); proxyClient.GetStudentAsync(); proxyClient.GetStudentCompleted += new EventHandler<GetStudentCompletedEventArgs>(proxyClient_GetStudentCompleted); } void proxyClient_GetStudentCompleted(object sender, GetStudentCompletedEventArgs e) { if (e.Error == null) { listStudent = e.Result; this.dgStudnet.ItemsSource = listStudent; } } }
運行結果:
將” SilverlightDemo”設置為啟動項目,運行,會產生下面的異常:

這就是因為當時建立項目的時候沒有把Silverlight程序和WCF服務放到同一個站點的緣故,因此需要在發布WCF的網站根目錄放置一個跨域文件:clientaccesspolicy.xml
clientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8"?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="SOAPAction"> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
再次運行,結果如下圖所示:

至此,Silverlight通過httbBingding方式訪問IIS宿主的WCF的演示我們就進行到這里。
下一篇我們將演示一下 Silverlight通過netTcpBinding方式訪問IIS宿主的WCF的環境配置和應該注意的問題。
