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.在类中声明私有属性也是会被序列化的哦!