Silverlight与WCF通信(一) :Silverlight通过httpBinding访问IIS宿主WCF
首语
本人在学习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)
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; } } }
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)
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" }); } } }
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 文件,代码如下:
<?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代码如下:
<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>
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
<?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的环境配置和应该注意的问题。