WCF 实际应用中 类序列化问题
发布日期:2021-06-29 01:52:51 浏览次数:2 分类:技术文章

本文共 3354 字,大约阅读时间需要 11 分钟。

                                              WCF  实际应用中 类序列化问题

在做wcf的时候遇到这样的一些问题:类与类相互嵌套会不会报错? 返回值的类型假如是一个实体类,不做契约声明,会不会影响返回值呢? 类与类的单向嵌套会不会影响返回结果?

1.类与类的互相嵌套,比如:有一个Person类和Dept类,Person里边有Dept,而Dept里也有Person,在接口使用Person实体对象传值

 类结构如下:  

 [DataContract]

  public class Person

    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public Dept dept { get; set; }
    }

   public class Dept

    {
        public string Name { get; set; }
        public Person person{ get; set; }
    }

接口实现如下:

     public string DoWork(Person pe)

        {
            return pe.Name;
        }

调用接口如下:

           //实例化Person类

            Person person = new Person();
            person.Name = "zhagnsan";
            //实例化Dept类
            Dept dept = new Dept();
            dept.Name = "55555555555";
            
            //关键在这    实例化的dept对象赋给Person里的dept对象,实例化的Person对象赋给Dept里的person对象,相互嵌套
            person.dept = dept;
            dept.person = person;

            ServiceReference1.Service1Client client = new Service1Client();
            client.DoWork1Completed += new EventHandler<DoWork1CompletedEventArgs>(client_DoWorkCompleted);
            client.DoWork1Async(person);

报错如下:

   尝试对参数 http://tempuri.org/ 进行序列化时出错: pe。InnerException 消息是““SilverlightApplication1.ServiceReference1.Dept”类型的对象图包含循环,如果不跟踪引用,择无法对其进行序列化。请考虑使用 IsReference 属性设为 True 的 DataContractAttribute。” 。有关详细信息,请参见 InnerException。

解决如下:

   实际问题不要类与类嵌套引用,至于解决方式需要根据自己的实际业务情况处理了。我这处理的是,Dept里包含Person,但Person不包含Dept.

2.返回值的类型假如是一个实体类,不做契约声明,例如:

我有一个Student类,但是我不加任何契约,也就表明不会被序列化

public class Student

    {
        public string Name { get; set; }
    }

接口实现如下:

 public Student   DoWork1(Person pe)

        {
            Student   model=new Student();
            model.Name = pe.Name;
            return model;
        }

调用如下:

   //实例化Person类

            Person person = new Person();
            person.Name = "zhagnsan";

            ServiceReference1.Service1Client client = new Service1Client();

            client.DoWork1Completed += new EventHandler<DoWork1CompletedEventArgs>(client_DoWorkCompleted);
            client.DoWork1Async(person);

          private void client_DoWork1Completed(object sender, DoWork1CompletedEventArgs e)

        {
            this.textBlock1.Text = e.Name;  //在实际的返回结果,我是可以获取到Student里的值的,但是在这强转Student对象是不可以的,即使你的Student对象和服务端的一样也不可以
        }

这个问题表明:WCF的使用中,只有使用类实体对象的时候(前提是加契约声明),才会被序列化,而返回值类型不受影响。

3.类与类的单向嵌套 ,其实也是我第一个问题中的解决方式,例如:

    public class Person

    {
        public string Name { get; set; }
    }

   [DataContract]

    public class Dept
    {

      [DataMember]

        public string Name { get; set; }

     [DataMember]

        public Person person{ get; set; }
    }

接口实现如下:

 public string DoWork(Dept de)

        {
            return pe.Name;
        }

接口调用如下:

  //实例化Person类

            Person person = new Person();
            person.Name = "zhagnsan";
            //实例化Dept类
            Dept dept = new Dept();
            dept.Name = "55555555555";

           dept.person = person;

           ServiceReference1.Service1Client client = new Service1Client();

            client.DoWork1Completed += new EventHandler<DoWork1CompletedEventArgs>(client_DoWorkCompleted);
            client.DoWork1Async(dept );

结果:

   接口正常返回,没有出错。

4.  在1中,我只给了Person类加了契约,而在3中我只给了Dept类加了契约,但是引用的类还是被序列化了。

     WCF中,类A包含类B,则给类A加契约就可以了,而不需要每个类都加一遍。

5. 类A包含类B,给类A加了契约,这样就是全部被序列化了,那么在类A中,我只不想让某个字段被序列化,怎么做呢? 

   public class Person

    {
        [NonSerialized] 
        private string _name;
        public string Name 
        {
            get { return _name; } 
            set { _name = value; } 
        }
    }
    [DataContract]
    public class Dept
    {
        [DataMember]
        private string Name { get; set; }
        [DataMember]
       public Person person{ get; set; }
    }

    虽然这样加了,但是不起作用,至于为什么,我就不知道了。。。

解决方式如下:

 [DataContract]

    public class Person
    {
        [NonSerialized] 
        private string _name;
        public string Name 
        {
            get { return _name; } 
            set { _name = value; } 
        }
    }
    [DataContract]
    public class Dept
    {
        [DataMember]
        private string Name { get; set; }
        [DataMember]
        public Person person{ get; set; }
    }

在引用的类加上契约就可以了

6.在类中声明私有属性也是会被序列化的哦!

 

转载地址:https://blog.csdn.net/yulinlin_fei/article/details/42029707 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:DataTable查询、修改、删除
下一篇:Idea配置方法注释模板

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月25日 09时57分00秒