zoukankan      html  css  js  c++  java
  • WCF进阶(二)——Contract

    前言

        我和用户有个约定,这个契约上篇已经说过了,分为服务契约、操作契约、消息契约、数据契约等,说白了,你到底让我看到什么,你告诉我,或者说,我可以让你看到什么,你敢用吗?下面就说一些基础的,关于这个些契约的分别定义,已经有什么其他的独特的之处。

    内容

    需要引用的命名空间

    using System.ServiceModel;
    

    [ServiceContract][OperationContract]

    指示接口或类在 Windows CommunicationFoundation (WCF) 应用程序中定义服务协定。

    就是约束对外提供的服务功能。它经常和操作契约(指示方法定义一个操作,该操作是 Windows Communication Foundation (WCF)应用程序中服务协定的一部分。)一起使用。

    Demo

     

        [ServiceContract]
        public interface IService
        {
            [OperationContract]
            Student GetStudentInfo();
        }

    效果

     

    上面的代码只是单方面强调了,对外提供的服务功能。具体的方法实现要在具体的类中说明。这时候问题来了,我怎么知道你调用了我的服务,我又怎么知道,我的这些效果实现是调用了你的服务,这个时候,就需要对这个操作契约设置通讯方式,这里分为单向和双向。采用IsOneWay属性来标识(如果还属性值为true,表明该操作是单向的,属性值为false,表明该操作是双向的)。

    单向Demo

     

        [ServiceContract(Namespace="WServer")]
        public interface IService
        {
            //isOneWay设置为true,表明该操作为单向的
            //设置为false,表明该操作作是双向的
            [OperationContract(IsOneWay=true)]
            /*
             * 启用单向通讯的方法,不能有返回值(void可以),不能有out参数,只允许传入参数
             */
            void AddInt(string message);
        }

    注意:约束的方法不能有返回值(void就可以),可以带有参数

    效果

     

    双向Demo

     

            //isOneWay设置为true,表明该操作为单向的
            //设置为false,表明该操作作是双向的
            [OperationContract(IsOneWay=false)]
    
            DateTime AddInt(string message);

    效果

     

    数据契约

    指定该类型要定义或实现一个数据协定,并可由序列化程序(如 System.Runtime.Serialization.DataContractSerializer)进行序列化。若要使其类型可序列化,类型作者必须为其类型定义数据协定。主要修饰属性和字段;带有该修饰,服务对外提供相应的属性和字段。

    普通Demo

     

        [DataContract]
        public class Employee
        {
            [DataMember]
            public string Name { get; set; }
            [DataMember]
            public int Age { get; set; }
            public string City { get; set; }
        }

    效果

     

    如果为了隐藏数据本身的身份,需要给身份起假名字对外提供。

    Demo

     

        [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; }
        }

    效果

     


    上面的修饰的数据类型都是一些普通的一些类型intstring等,在序列化和反序列化的时候,可以很容易的被识别进行操作,那么如果我想传递一个object类型的对象呢?反序列话需要怎么做才能让程序识别该类型并且完成反序列化。

    Demo

     

        [DataContract]
        //[KnownType(typeof(Dictionary<string,float>))]//为了解决object类型的反序列化--------没有解决
        [KnownType("GetKnowTypes")]//这个解决了object类型反序列化问题
        public class Student
        {
            [DataMember]
            public string Name;
            [DataMember]
            public string Phone;
            [DataMember]
            public AddrInfo Address;
            [DataMember]
            public object Scores;
            /*
             * 在一些比较复杂的类型的无法反序列化(不能识别类型)的时候,就得考虑使用knownTypeAttribute来标注可能涉及到的外部类型,但是如果遇到像泛型这些较为复杂的类型,就要考虑在带数据协定的类中添加一个静态方法,该方法返回Type的IEnumerable,一般是Type[]就可以了,而在KnownTypeAttribute的构造函数中使用这个方法的名字。
             */
            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;
        }

    效果

     

    小结

        关于消息契约和这个用法差不多,只不过,消息契约属性有头消息和正文消息修饰。

     

    感谢您的宝贵时间···

  • 相关阅读:
    第二期冲刺站立会议个人博客6(2016/5/30)
    第二期冲刺站立会议个人博客5(2016/5/29)
    “进度条”博客——第十三周
    第二次冲刺个人工作总结07
    第二次冲刺个人工作总结06
    第十三周学习进度
    第二次冲刺个人工作总结05
    第二次冲刺个人工作总结04
    课堂实验--贴吧找水王问题续
    第二次冲刺个人工作总结03
  • 原文地址:https://www.cnblogs.com/zhoulitong/p/6412314.html
Copyright © 2011-2022 走看看