0

默认是否XmlSerializer能够将类属性序列化为 Xml 属性?

[MyClassTypeAttribute(ClassType.MyClass)]
public MyClass : BaseClass {

}

会转向

<myclass MyClassType="MyClass">

原因

我有一个 WCF 服务,它通过同一个操作合同向我发送不同的对象,这些合同都派生自BaseClass. 要知道它是哪种类型的对象并将其直接转换(并将其序列化为 Xml 以在之后写入文档),我想要一些“类型”属性(enum)。

当然,一种可能性是将属性声明为XmlAttribute

[XmlAttribute(params)]
public MyClassType { get; set; }

这里的问题是:(XmlSerializer以及DataContractSerializer,AFAIK)迫使我setter在每个属性上都有一个。我知道我可以声明setterasprotected并且它仍然有效(XmlSerializer,你这个顽皮的小东西),但我不太喜欢那个解决方案,因为 1)我认为我通常可以在 POCO 中省略 setter 并且2) 将一些属性声明为 asXmlAttributes和另一些属性为 asXmlElements令人困惑(这就像将放入cat goulash中一样。

(此外,是否可以强制派生类声明某些属性?)

[abstract MyClassTypeAttribute]
4

1 回答 1

0

如果它是关于你的类的类型,这里是一个例子:

  [XmlIncludeAttribute(typeof(ConcreteFooOne))]
  [XmlIncludeAttribute(typeof(ConcreteFooTwo))]
  [XmlIncludeAttribute(typeof(ConcreteFooThree))]
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public abstract partial class AbstractFoo
  {
    // Some abstract props etc.
  }

  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public class ConcreteFooOne : AbstractFoo
  {
    public int MyProp { get; set; }
  }
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public class ConcreteFooTwo : AbstractFoo
  {

  }
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public class ConcreteFooThree : AbstractFoo
  {

  }

  class Program
  {
    static void Main(string[] args)
    {
      var serializer = new System.Xml.Serialization.XmlSerializer(typeof(AbstractFoo));
      using (var stream = new FileStream("test.txt", FileMode.OpenOrCreate))
      {
        serializer.Serialize(stream, new ConcreteFooOne() { MyProp = 10 });
        stream.Flush();
      }


      using (var stream = new FileStream("test.txt", FileMode.OpenOrCreate))
      {
        var c = serializer.Deserialize(stream);
      }
    }
  }

代码将序列化并包含 type 属性,当您反序列化时,您将获得正确的实例。

于 2013-08-06T13:40:41.677 回答