一、使用数据协定的好处:
1、使用数据协定可以灵活控制哪些成员应该被客户端识别。
2、隐藏真实身份(给类或成员取别名)
二、代码示例
1、服务端
定义实现数据协定的类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization; namespace Server { [DataContract] [KnownType(typeof(Dictionary<string,float>))] public class Student { /// <summary> /// 姓名 /// </summary> [DataMember] public string Name { get; set; } /// <summary> /// 电话 /// </summary> [DataMember] public int Phone { get; set; } /// <summary> /// 地址 /// </summary> [DataMember] public AddressInfo Address { get; set; } /// <summary> /// 成绩单 /// </summary> [DataMember] public object Scores { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.Serialization; namespace Server { [DataContract] public class AddressInfo { /// <summary> /// 省份 /// </summary> [DataMember] public string Province { get; set; } /// <summary> /// 城市 /// </summary> [DataMember] public string City { get; set; } /// <summary> /// 街道 /// </summary> [DataMember] public string Street { get; set; } } }
定义并启动服务
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.ServiceModel.Description; using System.Text; using System.Threading.Tasks; namespace Server { class Program { //声明并启动服务 static void Main(string[] args) { //服务器基地址 Uri baseUri = new Uri("http://localhost:1378/services"); //声明服务器主机 using (ServiceHost host = new ServiceHost(typeof(MyService),baseUri)) { //添加绑定和终结点 WSHttpBinding binding = new WSHttpBinding(); host.AddServiceEndpoint(typeof(IService), binding, "test"); //添加服务描述 host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true }); //启动服务 try { host.Open(); Console.WriteLine("服务已启动"); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); //关闭服务 host.Close(); } } } /// <summary> /// 定义服务协定 /// </summary> [ServiceContract] public interface IService { [OperationContract] Student GetStudentInfo(); } /// <summary> /// 实现服务协定 /// </summary> public class MyService : IService { public Student GetStudentInfo() { Student st = new Student { Name = "小刘", Phone = 123456, Address = new AddressInfo { Province = "四川省", City = "绵阳市", Street = "南山路" }, }; Dictionary<string, float> scores = new Dictionary<string, float>(); scores.Add("语文", 83.3f); scores.Add("数学", 90.7f); scores.Add("英语", 85.5f); st.Scores = scores; return st; } } }
2、客户端
先添加服务引用
再调用服务端的方法获取学生信息
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Client { class Program { static void Main(string[] args) { WS.ServiceClient sc = new WS.ServiceClient(); WS.Student st = sc.GetStudentInfo(); Console.WriteLine("学生信息:\n姓名:{0}\n电话:{1}\n地址信息:\n省份:{2}\n城市:{3}\n街道:{4}\n", st.Name, st.Phone, st.Address.Province, st.Address.City, st.Address.Street); Console.WriteLine("-----------------"); Console.WriteLine("成绩单"); Dictionary<string, float> scores = st.Scores as Dictionary<string, float>; foreach(var item in scores ) { Console.WriteLine("{0}:{1}", item.Key, item.Value); } Console.ReadKey(); } } }
温馨提示:在一些比较复杂的类型无法反序列化(不能识别类型)的时候,需要使用KnownTypeAttribute来标注可能涉及到的外部类型