【问题标题】:XML and DataContractSerializerXML 和 DataContractSerializer
【发布时间】:2009-03-25 20:15:32
【问题描述】:

我有这样的课程

[DataContract(Namespace = "")]
public class Foo
{
    [DataMember(Order = 0)]
    Bar bar;
}

[DataContract(Namespace = "")]
public class Bar
{
    Baz baz;

    [DataMember(Order = 0)]
    string TheBaz
    {
        get { baz.ToString(); }
        set { SomeOtherCode(value); }
    }
}

我希望它生成这样的 XML

<Foo>
    <Bar>String from baz.ToString()</Bar>
</Foo>

但我得到的更像是:

<Foo>
    <Bar><TheBaz>String from baz.ToString()</TheBaz></Bar>
</Foo>

有可能解决这个问题吗? This artical 表示 DataContractSerializer 的缺点之一是:

  1. 除了设置名称和顺序之外,无法控制对象的序列化方式

让我怀疑这是不是一个可解决的问题。


我知道这可以通过 IXmlSerializableReadXml/WriteXml 完成,因为我应该删除执行此操作的代码。

【问题讨论】:

    标签: .net xml datacontractserializer


    【解决方案1】:

    我意识到我的第一个答案完全是假的 - 但你可以用属性作弊:

    [DataContract(Namespace = "")]
    public class Foo
    {
        [DataMember(Order = 0, Name="Bar")]
        private string BazString {
            get {
                return bar == null ? null : bar.TheBaz.ToString();
            }
            set {
                if(value == null) {
                    bar = null;
                }
                else {
                    if(bar == null) bar = new Bar();
                    bar.TheBaz = value;
                }
            }
        }
    
        Bar bar;
    }
    

    【讨论】:

      【解决方案2】:

      Bar 类上实现IXmlSerializable,然后让它在序列化时输出&lt;Bar&gt;String from baz.ToString()&lt;/Bar&gt;

      您可以让 Foo 类保持原样,DataContractSerializer 将负责其余的工作。

      【讨论】:

      • 但是在这种情况下,您将如何处理“Bar”类中的其他属性?
      • 正是我已经摆脱的代码:)
      • @marc_s & BCS:如果您实现 IXmlSerializable,DataContractSerializer 将使用该实现作为输出,因此由实现者决定如何处理额外的属性。
      • @Marc Gravell:我不同意这里。使用您的方法,您必须对两段执行相同操作的代码进行两组测试,并且您必须始终保持它们同步。使用我的,你有两段独立的代码,它们做两件不同的事情,有不同的结果。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多