通过部分类

时间:2016-04-19 15:08:53

标签: c# partial xmlserializer

根据W3C,XSD布尔数据类型定义为0,1,true或false。外部方提供了一个我没有影响的xsd,因为您可能已经猜到了它们所需的布尔值不是C#XmlSerializer序列化布尔值的默认值。不接受真和假,只有0和1.更糟糕的是,序列化为xml的类是由xsd.exe自动生成的,因此我不想改变这些类,因为开发人员跟在我后面运行xsd.exe工具后,很可能会忘记这个额外的步骤。

因此,以下解决方案存在问题:

[XmlIgnore]
public bool MyValue { get; set; }

/// <summary>Get a value purely for serialization purposes</summary>
[XmlElement("MyValue")]
public string MyValueSerialize
{
    get { return this.MyValue ? "1" : "0"; }
    set { this.MyValue = XmlConvert.ToBoolean(value); }
}

同样根据我的理解,未来有可能将一些布尔值序列化为0或1而其他布尔值变为真或假(我知道......)。在出现这种情况之前,实现我的自定义XmlSerializer(参见:XML Serialize boolean as 0 and 1)可能是一个可接受的解决方案,但在此之前,我希望有人对以下有趣的可能性有一些提示:

假设xsd.exe已生成以下代码:

namespace MyUnitTests.Classes {
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:XX:YYYY:01")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:XX:01", IsNullable = false)]     
    public partial class MyRootClass {
        public MyBoolClass MyBoolClass { get; set; }
    }

    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "XX:ZZ:01")]
    public partial class MyBoolClass {
        [System.Xml.Serialization.XmlElementAttribute("Node")]
        public bool Item { get; set; }
    }
}

所以我的想法是MyBoolClass是一个部分类,我可以在一个单独的定义中提供我自己的自定义实现,我在其中处理真正的 - &gt; 1假 - &gt; 0问题。

我的代码如下:

namespace MyUnitTests.Classes {
    public interface IMyBoolClass {
        [XmlIgnore]
        bool Item { get; set; }
    }

    public partial class MyBoolClass : IMyBoolClass {
        [XmlElement("Node")]
        public string SerializableItem {
            get { return this.Item ? "1" : "0"; }
            set { this.Item = System.Xml.XmlConvert.ToBoolean(value); }
        }
    }
}

所以我有一个IMyBoolClass接口,我设计用来处理XmlIgnore并声明应该序列化实际0和1的属性SerializableItem。不幸的是,发生的异常表明XmlIgnore没有应用于MyBoolClass.Item,即由xsd.exe生成。

我有以下UnitTest

[TestMethod]
public void TestMethod2() {
    MyRootClass root = new MyRootClass() {
        MyBoolClass = new MyBoolClass() {
            Item = false
        }
    };

    XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyRootClass));

    using (StringWriter writer = new StringWriter()) {
        xmlSerializer.Serialize(writer, root);
        string xml = writer.ToString();
    }
}

发生以下异常:

There was an error reflecting property 'MyBoolClass
There was an error reflecting property 'Item'
The XML element 'Node' from namespace 'XX:ZZ:01' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element

显然正在改变:

[XmlElement("Node")]

在我自己的MyBoolClass部分定义中:

[XmlElement("Node1")] 

解决问题并产生以下XML:

<?xml version="1.0" encoding="utf-16"?>
<MyRootClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:XX:01">
  <MyBoolClass xmlns="urn:XX:YYYY:01">
    <Node1 xmlns="XX:ZZ:01">0</Node1>
    <Node xmlns="XX:ZZ:01">false</Node>
  </MyBoolClass>
</MyRootClass>

所以问题如何“隐藏”:

public bool Item { get; set; }

在xsd.exe为XmlSerializer生成的类MyBoolClass中?

任何提示和技巧都将受到高度赞赏,如果有人有其他一些好主意,我将非常感激。

0 个答案:

没有答案