本文共 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!