【问题标题】:how to serialize a System.Type object with XmlSerializer?如何使用 XmlSerializer 序列化 System.Type 对象?
【发布时间】:2011-07-18 12:58:53
【问题描述】:

考虑这种类型:

  [DataContract]
  public class EntityId
  {
    [DataMember(Order = 1)]
    public string IdAsString { get; set; }
    [DataMember(Order = 2)]
    public Type Type { get; set; }
  }

我为它创建了一个 Xml 序列化程序程序集。但是,尝试对其进行序列化会产生异常:

System.InvalidOperationException occurred
  Message=The type NC.DTO.FlowFolder was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
  Source=NC.DTO.XmlSerializers
  StackTrace:
       at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write3_Type(String n, String ns, Type o, Boolean isNullable, Boolean needType)
  InnerException: 

NC.DTO.FlowFolder 实际上是 typeof(NC.DTO.FlowFolder) 的字符串表示形式 - Xml 序列化程序知道 NC.DTO.FlowFolder 类型,但似乎无法序列化的是 Type对象本身。

反射器显示失败的方法内容:

private void Write3_Type(string n, string ns, Type o, bool isNullable, bool needType)
{
    if (o == null)
    {
        if (isNullable)
        {
            base.WriteNullTagLiteral(n, ns);
        }
    }
    else if (!needType && (o.GetType() != typeof(Type)))
    {
        throw base.CreateUnknownTypeException(o);
    }
}

注意throw 声明。

堆栈跟踪是:

NC.DTO.XmlSerializers.dll!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write3_Type(string n, string ns, System.Type o, bool isNullable, bool needType) + 0xda bytes    
NC.DTO.XmlSerializers.dll!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write11_EntityId(string n, string ns, NC.DTO.EntityId o, bool isNullable, bool needType) + 0x2a8 bytes  
NC.DTO.XmlSerializers.dll!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write14_FlowFolder(string n, string ns, NC.DTO.FlowFolder o, bool isNullable, bool needType) + 0x36b bytes  
NC.DTO.XmlSerializers.dll!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write42_FlowFolder(object o) + 0xc9 bytes   
[Native to Managed Transition]  
System.Xml.dll!System.Xml.Serialization.TempAssembly.InvokeWriter(System.Xml.Serialization.XmlMapping mapping, System.Xml.XmlWriter xmlWriter, object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, string encodingStyle, string id) Line 342 + 0xb9 bytes    C#
System.Xml.dll!System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter xmlWriter, object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, string encodingStyle, string id) Line 676 + 0xdf bytes   C#
System.Xml.dll!System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter xmlWriter, object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces, string encodingStyle) Line 646   C#
System.Xml.dll!System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter xmlWriter, object o, System.Xml.Serialization.XmlSerializerNamespaces namespaces) Line 640 C#
System.Xml.dll!System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter xmlWriter, object o) Line 616  C#

我的问题是如何让 Xml 序列化程序乐于序列化和反序列化 EntityId 对象?

谢谢。

附言

如果有人知道另一种 Xml 序列化库,可以将 XML 序列化为 Newtonsoft.Json 到 JSON 序列化 - 请分享。

【问题讨论】:

    标签: .net xml xml-serialization


    【解决方案1】:

    xml 通常旨在独立于平台,因此为什么它不起作用。你可以试试:

    [XmlIgnore]
    public Type Type { get; set; }
    [XmlElement("Type")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public string AssemblyQualifiedTypeName
    {
        get { return Type == null ? null : Type.AssemblyQualifiedName; }
        set { Type = string.IsNullOrEmpty(value) ? null : Type.GetType(value); }
    }
    

    另请注意,如果您使用XmlSerializer,则数据合同属性无效。另请注意,这会将您绑定到 .NET 和可能的特定版本等。

    【讨论】:

    • 数据合约属性适用于 protobuf-net :-)。
    • 我可以在EntityId声明之外做这个技巧吗?我想把它作为序列化引擎的实现细节,而不是泄露到 EntityId 的声明中。
    • @mark AFAIK,仅当您在 DTO 中替换了另一个对象时。因此,如果您的意思是“并保持清洁”;然后....没有。
    • @mark 我一直在想我应该尝试在 protobuf-net 元/发射层之上编写一个 XmlSerializer 版本;但这一切都归结为时间。
    • @MarcGravell 让我们continue this discussion in chat
    猜你喜欢
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多