ffxdz
来自反方向的钟。本博客所有文章均为原创,如有雷同,一定是他人转载本博客。

导航

 

      没有安排的时间很容易就被浪费掉,今天虽然很早醒,但是赖在床上到中午才下床。今天中午为了在一个碗里泡两包统一老坛酸菜牛肉面,滚烫的开水装太满淋在了我的右手上,好JB疼!下午被我群里几百号屌丝@得我的QQ都卡掉了。今天真够倒霉的。

     写了好几篇博文了,虽说也算是在分享技术,但很明显的让我感觉到,我就像在自言自语,缺乏读者的博文让人写得很枯燥。但我最近认清楚了一件事情,现在更多的企业看的一个人现在会什么而不是一个人的学习能力,作为一个几乎所有开发知识都靠自己学习与实践的专升本应届毕业生,我觉得很无奈,却心有不甘。于是我决定,我要用博客记录我技术人生中的一切,将博客地址加入到简历中,总会有一天,有一个关键的人会看到我博客里记录的努力。我将此称作“永不放弃的曲线逆袭”。

     现在开始来写今天的内容。

     数据契约是soap里很重要的一块,他涉及到了一个叫做序列化和反序列化的概念。序列化理解起来也很简单,就是将你面向对象里学的对象转换成一个方便用于传输的文本格式,反序列化则是将这么一段文本格式,还原成我们编程知识里的对象。soap从头到尾用的都是http来传输数据,那序列化和反序列化的介质自然就是最常见的XML了。XML听起来很吓人对吧,别害怕,这个正反序列化的过程,微软大牛全部帮你封装好了,我们要做的只是在学好编程知识之余,掌握好数据契约的知识。

     我们现在要做到的事情,是将一个自定义的类型对象从服务端传到客户端,这个对象中可能包含着基本类型字段(int\double\float\string等)和属性。

建立一个类,里面包含这若干个字段

    public class test
    {
        public int a;
        public int b;
        public int c;
        private int d;
    }

在服务接口中加入

test gettest(int i, int j, int k);

在实现服务接口的类中加入

(如果不在实现服务接口的类中加入test类型返回值的函数,则无法将test序列化传输至客户端,所以一定要加一个这样的函数)

public hellowcf.test gettest(int i, int j, int k)
        {
            test t = new test();
            t.a = i;
            t.b = j;
            t.c = k;
            return t;
        }

客户端得到的是

只有a,b,c,没有d。将d的private改为public就有了。

将test类加上[DataContract]和[DataMember]两个标签,代码顶部加上using System.Runtime.Serialization;

[DataContract]
    public class test
    {
        [DataMember]
        public int a;
        [DataMember]
        public int b;
        [DataMember]
        public int c;
        [DataMember]
        private int d;
    }

客户端得到的是

好了,加上[DataMember]后在序列化的过程中私有的会被转换成公有的,所以private加上[DataMember]成为数据成员之后就不再私密。

到这里似乎还看不出来数据成员有什么用,我也学的很困惑。但大家有想过这样一种情况

    [DataContract]
    public class test
    {
        [DataMember]
        public int a
        {
            get { return _a; }
            set { this._a = value; }
        }
        [DataMember]
        public int b
        {
            get { return _b; }
            set { this._b = value; }
        }
        public int c
        {
            get { return _c; }
            set { this._c = value; }
        }
        public int d
        {
            get { return _d; }
            set { this._d = value; }
        }
        private int _a;
        private int _b;
        private int _c;
        private int _d;
    }

这就是大家学C#中见到过的属性,用来对输入输出进行限制的东西。

客户端是这样的:

那我就明白数据协议是有什么用了。

总结一下:基本类型的public状态,加不加[DataMember]都能被序列化。基本类型的private状态,不加[DataMember]不会被序列化,加了[DataMember]会在被序列化的过程中转换成public状态。至于属性,加[DataMember],public可以序列化但private不行,不加[DataMember]的全部不能序列化。所有内容,序列化了就能在客户端访问到,无法序列化的就无法在客户端访问到。不要问我为什么,因为微软就是这么规定的。

至于涉及泛型的数据类型,通过以上方法貌似就不能使用以上方法顺利在服务端和客户端之间传输,必应了一下,解决方案和KnownTypeAttribute 类有关,这种那么高级的东西我这里就不讲解了。

KnownTypeAttribute 类:

http://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.knowntypeattribute(v=vs.110).aspx

 

不知道为什么我学起来觉得好麻烦,还一个一个去试着做一下,我自己描述起来能说得那么简洁,不知道大家看懂了没?

posted on 2014-03-18 22:01  ffxdz  阅读(408)  评论(1编辑  收藏  举报