类属性的序列化?

时间:2013-08-06 13:31:17

标签: c# .net xml wcf serialization

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

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

}

会转向

<myclass MyClassType="MyClass">

原因

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

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

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

问题在于:XmlSerializerDataContractSerializer以及AFAIK)迫使我在每个属性上都有setter。我知道我可以将setter声明为protected并且它仍然有效( XmlSerializer,你顽皮的小事),但是不喜欢那个解决方案,因为1)我认为有一个原因是我能够通常忽略POCO中的setter,2)将某些属性声明为XmlAttributes而将其他属性声明为XmlElements令人困惑(这就像放置进入猫炖牛肉

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

[abstract MyClassTypeAttribute]

1 个答案:

答案 0 :(得分: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属性,当您反序列化时,您将获得正确的实例。