一、使用数据协定的好处:
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来标注可能涉及到的外部类型