2009-05-05 143 views
4

在上一个关于serialising an object to an XmlDocument in C#的问题中,我需要将一些故障信息序列化为从asmx样式web服务调用返回的XmlDocument。在客户端,我需要将XmlDocument反序列化为一个对象。序列化为XML并包含序列化对象的类型

如果你知道类型,这很简单,但是我意识到我想要一个灵活的方法,其中去序列化的类型也编码在XmlDocument中。目前,我正在做手工通过添加XmlNode到具有类型名称XmlDocument,计算如下:

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; 

所以这是一个暴力的做法,我想知道如果有一个更优雅的解决方案,它以某种方式包括序列化类型的类型名称自动,而非手动录音它在别处吗?

回答

3

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

我看到你正在切割组装版本,因为我也是。但我想提一提,那你将有泛型类型的麻烦为他们签名看起来像这样:

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 

所以我做了一个函数来仅切出集版本(S),这似乎是足以摆脱版本问题:

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; 
    } 
0

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

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

另外,你有这么多不同的故障类型,一个简单的开关声明不能确定正确的类型使用?

+0

我在服务器和客户端上使用asmx,是的。我正在实施一种类似WCF的故障系统,因为在客户端我使用的是asmx服务的接口,我不希望该接口的用户获得SoapExceptions,所以他们得到了一些东西我用一个Fault属性来调用一个ServiceException。该故障属性返回到SoapException.Detail属性中的asmx客户端,因此是XmlDocument/XmlNode序列化。目前我的故障类型并不多,但我希望可以灵活地向服务器添加更多内容,而不会中断部署的客户端。 – 2009-05-05 10:07:42

+1

所以,你不是在重新发明轮子;你正在重塑WCF。 – 2009-05-05 10:21:19

相关问题