我正在将xml发送到另一个程序,它希望布尔标志为"是"或"否",而不是"真"或"假".
我有一个类定义如下:
[XmlRoot()] public class Foo { public bool Bar { get; set; } }
当我序列化它时,我的输出如下所示:
true
但我希望它是这样的:
yes
我可以在序列化时这样做吗?我宁愿不必诉诸于此:
[XmlRoot()] public class Foo { [XmlIgnore()] public bool Bar { get; set; } [XmlElement("Bar")] public string BarXml { get { return (Bar) ? "yes" : "no"; } } }
请注意,我还希望能够再次反序列化此数据.
好的,我一直在研究这个问题.这是我想出的:
// use this instead of a bool, and it will serialize to "yes" or "no" // minimal example, not very robust public struct YesNo : IXmlSerializable { // we're just wrapping a bool private bool Value; // allow implicit casts to/from bool public static implicit operator bool(YesNo yn) { return yn.Value; } public static implicit operator YesNo(bool b) { return new YesNo() {Value = b}; } // implement IXmlSerializable public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { Value = (reader.ReadElementContentAsString() == "yes"); } public void WriteXml(XmlWriter writer) { writer.WriteString((Value) ? "yes" : "no"); } }
然后我将我的Foo类更改为:
[XmlRoot()] public class Foo { public YesNo Bar { get; set; } }
请注意,因为YesNo
可以隐式转换为bool
(反之亦然),您仍然可以执行此操作:
Foo foo = new Foo() { Bar = true; }; if ( foo.Bar ) { // ... etc
换句话说,你可以像对待bool一样对待它.
而且!它序列化为:
yes
它也正确地反序列化.
可能有一些方法可以让我的XmlSerializer自动将bool
它遇到的任何s转换为YesNo
s - 但我还没有找到它.任何人?
非常简单.使用代理财产.在实际属性上应用XmlIgnore.代理是一个字符串,必须使用带有元素名称覆盖的XmlElement属性.指定覆盖中实际属性的名称.代理属性根据实际属性的值进行不同的序列化.您还必须为Surrogate提供一个setter,并且setter应该适当地设置实际属性,无论它序列化什么值.换句话说,它需要双向进行.
剪断:
public class SomeType { [XmlElement] public int IntValue; [XmlIgnore] public bool Value; [XmlElement("Value")] public string Value_Surrogate { get { return (Value)? "Yes, definitely!":"Absolutely NOT!"; } set { Value= (value=="Yes, definitely!"); } } }
单击此处获取完整的可编译源示例.