事先不知道派生类型时使用DataContractSerializer反序列化派生类型

时间:2012-10-12 12:47:01

标签: c# deserialization datacontractserializer

在汇编A中:

[DataContract]    
        public class Base
        {
            [DataMember]
            public string SomeText { get; set; }
        }

在大会B中:

internal class Helper
        {
           internal static Base Deserialize(string serializedInstanceOfTypeBase)
    {
                   DataContractSerializer serializer = new DataContractSerializer(typeof (Base));
                    XmlReader reader = XmlReader.Create(new StringReader(serializedInstanceOfTypeBase));
                    return (Base)serializer.ReadObject(reader);
    }
    }

在汇编C中:

[DataContract]    
        public class Derived : Base
        {
            [DataMember]
            public string SomeMoreText { get; set; }
        }

如果我序列化Derived类型的实例并将其传递给Helper.Deserialize()方法,则会失败并显示SerializationException

  

第1行位置出错2.期望命名空间中的元素“Base”   'http://schemas.datacontract.org/2004/07'..遇到'元素'   名称为'Derived',名称空间   'http://schemas.datacontract.org/2004/07'。

如何解决此问题?

我知道KnownType属性,但在编译程序集A和B时,我完全不知道它的派生类型。所以我不能使用那个解决方案。

我的产品设计更复杂,我不能完全在这里发布。 Helper.Desrialize()方法只获取string参数。即使在运行时,也无法(至少目前)对程序集A或B了解Base类的派生类型。

装配B引用装配A.但A& B不能参考组件C.

我正在使用C#4.0。如果您提供的解决方案不使用DataContractSerializer,则可以。

2 个答案:

答案 0 :(得分:3)

您是否知道在运行时的类型?如果是这样,一个简单的方法可能只是:

List<Type> knownTypes = ...; // now that you know what to expect
DataContractSerializer serializer = new DataContractSerializer(
    typeof(Base), knownTypes);

答案 1 :(得分:2)

看起来你需要两个:

  • 将一组KnownTypes传递给您的反序列化器(如上所述)
  • 告诉反序列化程序不要检查类型(使用verifyObjectName参数):

    return (Base)serializer.ReadObject(reader, false);
    

在此处查看详情: http://msdn.microsoft.com/en-us/library/ms573850%28v=vs.110%29.aspx