首页 > 代码库 > 重温WCF之数据契约(四)

重温WCF之数据契约(四)

1.使用数据协定可以灵活控制哪些成员应该被客户端识别。

    [DataContract]
    public class Employee
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public int Age { get; set; }
        [DataMember]
        public string City { get; set; }
    }
    
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        Employee GetAEmployee();
    }

    public class MyService : IService
    {
        public Employee GetAEmployee()
        {
            return new Employee { Name = "小朋友", Age = 32 };
        }
    }
    class Program
    {
       static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(Service1)))
            {
                host.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "http://127.0.0.1:8888/service1");
                ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                behavior.HttpGetEnabled = true;
                behavior.HttpGetUrl = new Uri("http://127.0.0.1:8888/service");  //httpGetUrl客户端引用的地址
                host.Description.Behaviors.Add(behavior);
                host.Opened += delegate
                {
                    Console.WriteLine("服务已启动");
                    Console.ReadKey();
                };
                host.Open();
            }
        }
    }

如果把Employee类中的某个成员的DataMember属性去掉,则在客户端代理类中就不会生成该属性

2.数据协定也有隐藏真实身份的作用

    [DataContract(Name = "Worker")]
    public class Employee
    {
        [DataMember(Name = "Worker_Name")]
        public string Name { get; set; }

        [DataMember(Name = "Worker_Age")]
        public int Age { get; set; }

        [DataMember(Name = "Worker_City")]
        public string City { get; set; }
    }

这样在客户端生成的代理类的成员名称就和服务器端不一样

3.在一些比较复杂的类型无法反序列化(不能识别类型)的时候,就得考虑使用KnownTypeAttribute来标注可能涉及到的外部类型,但如果遇到像泛型这些较为复杂的类型,就要考虑在带数据协定的类中添加一个静态方法,该方法返回Type 的IEnumerable,一般是Type[]就可以了,而在KnownTypeAttribute的构造函数中使用这个方法的名字

[DataContract]
    [KnownType("GetKnowTypes")]
    public class Student
    {
        [DataMember]
        public string Name;
        [DataMember]
        public string Phone;
        [DataMember]
        public AddrInfo Address;
        [DataMember]
        public object Scores;

        static Type[] GetKnowTypes()
        {
            return new Type[] { typeof(Dictionary<string,float>) };
        }
    }
    [DataContract]
    public class AddrInfo
    {
        [DataMember]
        public string Province;
        [DataMember]
        public string City;
        [DataMember]
        public string DetailAddr;
    }
      public class MyService : IService
    {
        public Student GetStudentInfo()
        {
            Student stu = new Student();
            AddrInfo info = new AddrInfo();
            info.Province = "广东省";
            info.City = "佛山市";
            info.DetailAddr = "火星路-300号";
            stu.Name = "小陈";
            stu.Phone = "1388888888";
            stu.Address = info;
            Dictionary<string, float> m_scores = new Dictionary<string, float>();
            m_scores.Add("语文", 97f);
            m_scores.Add("英语", 64.5f);
            m_scores.Add("数学", 38f);
            m_scores.Add("历史", 77.6f);
            m_scores.Add("地理", 82.3f);
            stu.Scores = m_scores;
            return stu;
        }
    }
 static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(Service1)))
            {
                host.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "http://127.0.0.1:8888/service1");
                ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                behavior.HttpGetEnabled = true;
                behavior.HttpGetUrl = new Uri("http://127.0.0.1:8888/service");  //httpGetUrl客户端引用的地址
                host.Description.Behaviors.Add(behavior);
                host.Opened += delegate
                {
                    Console.WriteLine("服务已启动");
                    Console.ReadKey();
                };
                host.Open();
            }
        }


        static void Main(string[] args)
        {
            WS.ServiceClient cli = new WS.ServiceClient();
            WS.Student stu = cli.GetStudentInfo();
            string msg = "学生姓名:{0}\n联系电话:{1}\n" +
                        "地址信息:-----------\n" +
                        "省份:{2}\n" +
                        "市区:{3}\n" +
                        "详细地址:{4}";
            Console.WriteLine(msg, stu.Name, stu.Phone, stu.Address.Province, stu.Address.City, stu.Address.DetailAddr);
            Console.WriteLine("---------------------------------------");
            Console.WriteLine("学生成绩单:");
            Dictionary<string, float> scores = stu.Scores as Dictionary<string, float>;
            foreach (var item in scores)
            {
                Console.Write("{0}:{1}\n", item.Key, item.Value);
            }

            Console.ReadKey();
        }