Serialise to XML并包含序列化对象的类型

在上一个关于在C#中将对象序列化为XmlDocument中 ,我需要将一些错误信息序列化为从asmx样式的webservice调用返回的XmlDocument 。 在客户端上,我需要将XmlDocument反序列化回一个对象。

如果您知道类型,这很简单,但我意识到我想要一种灵活的方法,其中反序列化的类型也在XmlDocument编码。 我目前正在通过向具有类型名称的XmlDocument添加XmlNode手动执行此操作,计算方法如下:

  Type type = fault.GetType(); string assemblyName = type.Assembly.FullName; // Strip off the version and culture info assemblyName = assemblyName.Substring(0, assemblyName.IndexOf(",")).Trim(); string typeName = type.FullName + ", " + assemblyName; 

然后在客户端上我首先从XmlDocument获取此类型名称,并创建传递给XmlSerialiser的类型对象:

  object fault; XmlNode faultNode = e.Detail.FirstChild; XmlNode faultTypeNode = faultNode.NextSibling; // The typename of the fault type is the inner xml of the first node string typeName = faultTypeNode.InnerXml; Type faultType = Type.GetType(typeName); // The serialised data for the fault is the second node using (var stream = new StringReader(faultNode.OuterXml)) { var serialiser = new XmlSerializer(faultType); objectThatWasSerialised = serialiser.Deserialize(stream); } return (CastToType)fault; 

所以这是一种蛮力的方法,我想知道是否有更优雅的解决方案,以某种方式自动包含序列化类型的类型名称,而不是手动将其记录到别处?

我遇到了类似的问题,我提出了相同的解决方案。 就我而言,这是将类型与XML序列化中的值保持在一起的唯一方法。

我看到你正在切割assembly版本,因为我也做了。 但是我想提一下,你会遇到generics类型的麻烦,因为他们的签名看起来像:

 System.Nullable`1[[System.Int, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 

所以我做了一个只删除程序集版本的函数,这似乎足以摆脱版本问题:

  private static string CutOutVersionNumbers(string fullTypeName) { string shortTypeName = fullTypeName; var versionIndex = shortTypeName.IndexOf("Version"); while (versionIndex != -1) { int commaIndex = shortTypeName.IndexOf(",", versionIndex); shortTypeName = shortTypeName.Remove(versionIndex, commaIndex - versionIndex + 1); versionIndex = shortTypeName.IndexOf("Version"); } return shortTypeName; } 

尼尔,为什么你需要它在客户端和服务器上是相同的类型?

你还在客户端上使用ASMX吗? 这是一个原因,因为ASMX不能正确支持故障。

此外,您是否有这么多不同的故障类型,简单的switch语句无法确定要使用的正确类型?