体验一下WCF
标题有有意思,说是再次看WCF,意思是说之前也简单的看过,但没有用到实际项目中来,这一次,准备大规模的体验一下WCF。
今天主要是一个例子,从用户服务器,根据指定用户ID,还回它的用户实体,即,用户模块的代码是写好的,可以供其它项目,业务去调用,提供一个开放的服务平台,先看一下结构图
在WCF Service文件夹中,Contracts是指定义服务契约(Service Contract),引用System.ServiceMode程序集
Service提供对WCF服务的实现。即在契约Contracts的实现,所以Services具有对Contracts项目的引用;
Hosting实现对定义在Services项目中的服务的寄宿,它可以由控制台程序实现,也可以发布到IIS上。
Client是一个客户端程序,它有对Service的服务引用,主要从Service中获取服务
Entity和VCommons都是公用项目, 在我的这篇博文中有说明
下面我们来一步一步创建这个WCF程序
一 建立Contracts契约,代码如下:
[ServiceContract(Name = " UserService " , Namespace = " http://www.wcf.com/ " )] public interface IUser { [OperationContract] bool Register(Entity.UserBases entity); [OperationContract] byte [] GetUserByID( int userID); [OperationContract] UserBases GetUserBaseByID( int userID); }
我们看到,它实事上就是一种操作的规范,我们在WCF里叫它服务规范或服务契约
二 建立Service项目,代码如下:
public class UserService : IUser { static Entity.Car_RentalDataContext db; static UserService() { db = new Entity.Car_RentalDataContext(System.Configuration.ConfigurationManager.ConnectionStrings[ " Car_Rental " ].ToString()); } public bool Register(Entity.UserBases entity) { try { db.UserBases.InsertOnSubmit(entity); db.SubmitChanges(); return true ; } catch (System.Exception) { return false ; throw ; } } public byte [] GetUserByID( int userID) { return VCommons.SerializationHelper.ObjectToByteArray(db.GetTable<UserBases>().Select(i => new UserBases_Ext { UserID = i.UserID, Name = i.Name, }).FirstOrDefault(i => i.UserID == userID)); } }
事实上,WCF服务就是要把服务契约进行实现,我进行了一个简单的测试,WCF也是走SOAP协议,所以 Register(Entity.UserBases entity) 这种方法肯定是不行的,我们需要将它进
行序列化。
三 创建服务宿主,事实上,我们最习惯的宿主方式就是像WebService式的IIS宿主,原来WS里有ASMX,现在WCF里叫SVC,先看一个SVC文件内容如下:
1 <%@ ServiceHost Service= " Artech.WcfServices.Services.UserService " %>
直接使用ServiceHost即可,注册,在项目中,要引用System.ServiceModel程序集。
再看一下控制台程序的宿主代码:
1 class Program 2 { 3 static void Main( string [] args) 4 { 5 using (ServiceHost host = new ServiceHost( typeof ( UserService))) 6 { 7 8 host.AddServiceEndpoint( typeof (IUser), new WSHttpBinding(), " http://127.0.0.1:9999/UserService " ); 9 if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null ) 10 { 11 ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); 12 behavior.HttpGetEnabled = true ; 13 behavior.HttpGetUrl = new Uri( " http://127.0.0.1:9999/ UserService/metadata " ); 14 host.Description.Behaviors.Add(behavior); 15 } 16 host.Opened += delegate 17 { 18 Console.WriteLine( " Service已经启动 " ); 19 20 }; 21 22 host.Open(); 23 Console.Read(); 24 } 25 26 } 27 28 }
而对于,客户端来说,我们需要对Service项目进行服务引用
如果你的服务是一个获取数据源的服务,WCF还会在你的项目中生成一个.datasource的数据源,client项目代码如下:
1 using (UserServiceClient proxy = new UserServiceClient()) 2 { 3 UserBases_Ext entity = (UserBases_Ext)VCommons.SerializationHelper.ByteArrayToObject(proxy.GetUserByID( 1 )); 4 Console.Write(entity == null ? " 没有找到 " : entity.Name); 5 6 UserBases entity2 = proxy.GetUserBaseByID( 1 ); // soap不支持复杂类型 7 Console.Write(entity2 == null ? " 没有找到 " : entity2.Name); 8 Console.ReadKey(); 9 }
OK,到这里,我们的第一个WCF实例就完成了。
注意:linq to sql生成的实体,再进行序列化时,会报异常的,我们需要为它和它的派生类重新做序列化标记,然后返回数据时,使用派生类型和可以,代码如下:
1 [Serializable] 2 public partial class UserBases 3 { 4 // linq实体扩展功能 5 } 6 [Serializable] 7 public class UserBases_Ext : UserBases // UserBases_Ext和UserBases需要同时被标记为可序列化 8 { }
分类: WCF , 面向服务
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息