在大多数情况下使用 DataContract(s) 就足够了,但在互操作性场景中需要自定义序列化。虽然 .NET 不使用“是”和“否”作为布尔值,但其他平台/语言可能会这样做。因此,您必须利用 WCF 中的其他序列化方法。
考虑实现数据协定的 IXmlSerializable 接口,该接口允许您在低级别控制序列化和反序列化。
考虑这个在 WCF 服务中使用的 POCO 示例:
public class Animal : IXmlSerializable
{
public Animal()
{
}
bool _isBipedal;
public bool IsBipedal
{
get { return _isBipedal; }
set { _isBipedal = value; }
}
string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
Name = reader.GetAttribute("Name");
reader.ReadStartElement();
IsBipedal = bool.Parse(reader.ReadElementString("IsBipedal") == "Yes" ? "true" : "false");
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Name", Name);
writer.WriteElementString("IsBipedal", IsBipedal ? "Yes" : "No");
}
}
请注意,此类不使用 [DataContract] 属性,而是实现 IXmlSerializable。针对 WCF 操作运行客户端后
返回这个Animal类型的列表,我们得到以下序列化的内容(注意我们这里的wire/response可以使用“Yes”作为布尔值用Fiddler检查:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><GetAnimalsResponse xmlns="http://tempuri.org/"><GetAnimalsResult xmlns:a="http://schemas.datacontract.org/2004/07/CustomWcfSerialization.Common" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
否是
关于 IXmlSerializable - 请注意,ReadXml 方法将负责反序列化对象,而 WriteXml 方法将负责序列化对象。 GetSchema 方法在大多数情况下可以返回 null。
我准备了一个带有 Visual Studio 解决方案的小型演示项目,展示了如何在此处完成此操作:
git clone git@bitbucket.org:toreaurstad/wcfixmlserializabledemo.git