c#布尔序列化问题
我有一个值希望反序列化为布尔值,但反序列化不支持给定的情况,即:FALSE或TRUE,并且提供的格式很难更改,我会引发异常:c#布尔序列化问题,c#,boolean,deserialization,C#,Boolean,Deserialization,我有一个值希望反序列化为布尔值,但反序列化不支持给定的情况,即:FALSE或TRUE,并且提供的格式很难更改,我会引发异常: System.FormatException: The string 'FALSE' is not a valid Boolean value. 我知道这是因为XMLSerialiser不支持这一点;只允许使用有效的XML模式值,如“false”或“true”(第一位研究,请检查!) 因此,第一种选择是创建一个字符串属性来进行转换,如下所示: public class
System.FormatException: The string 'FALSE' is not a valid Boolean value.
我知道这是因为XMLSerialiser不支持这一点;只允许使用有效的XML模式值,如“false”或“true”(第一位研究,请检查!)
因此,第一种选择是创建一个字符串属性来进行转换,如下所示:
public class MyExample
{
[XmlIgnore] public bool _booleanField { get; set; }
[XmlElement("BooleanField")]
public string BooleanFieldString
{
get => _booleanField.ToString().ToLower();
set => _booleanField = ConvertBooleanStringValue(value);
}
private bool ConvertBooleanStringValue(string booleanAsString)
{
switch (booleanAsString.ToUpper())
{
case "TRUE":
case "T":
case "1":
case "Y":
case "YES":
return true;
case "FALSE":
case "F":
case "0":
case "N":
case "NO":
return false;
default:
return false;
}
}
}
但我不喜欢这样,因为它会弄乱我构建的干净类,并且需要围绕我在28个类中拥有的所有布尔值(第二点研究,检查!)
我收到的XML可能会传递很多布尔值,用于各种参数,因此如果我选择解析源数据,我需要知道所有布尔元素是什么。这里的限制是XMLSerialiser,虽然这不是它的错,但我明白了
我可以实现ISerializable接口并编写一个特定的实现,但对于布尔值来说这是一个很大的工作,从我所做的研究来看,我不相信有一种方法可以仅对特定属性这样做,这显然会限制痛苦(第三点研究!!!)
还有其他序列化框架,可以像ExtendedXmlSerializer一样解决这个问题,但如果可能的话,我宁愿坚持我所知道的。前提是您可以识别所有需要这个可选解析例程的布尔元素,您可以实现自定义的
XmlTextReader
,并将其传递给常规的XmlSerializer
下面的CustomXmlReader
接受需要特别注意的xml元素名称列表
public class CustomXmlReader : XmlTextReader
{
private readonly IList<String> _booleanFieldNames;
private Boolean _parseBooleanString;
public CustomXmlReader(IList<String> booleanFieldNames, TextReader reader) : base(reader)
{
this._booleanFieldNames = booleanFieldNames;
}
public override XmlNodeType MoveToContent()
{
XmlNodeType nodeType = base.MoveToContent();
this._parseBooleanString = ((XmlNodeType.Element == nodeType)
&& this._booleanFieldNames.Contains(this.Name)
);
return nodeType;
}
public override String ReadString()
{
String value = base.ReadString();
if (this._parseBooleanString)
{
if (value.Equals("TRUE", StringComparison.OrdinalIgnoreCase)
|| value.Equals("T", StringComparison.OrdinalIgnoreCase)
|| value.Equals("1", StringComparison.OrdinalIgnoreCase)
|| value.Equals("YES", StringComparison.OrdinalIgnoreCase)
|| value.Equals("Y", StringComparison.OrdinalIgnoreCase)
)
{
return "true";
}
return "false";
}
return value;
}
}
下面的代码解析以下xml结构
const String XML = @"
<MyExample>
<BooleanField>T</BooleanField>
</MyExample>";
using (var stringReader = new StringReader(XML))
using (var xmlReader = new CustomXmlReader(new List<String> { "BooleanField" }, stringReader))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyExample));
MyExample mx = serializer.Deserialize(xmlReader) as MyExample;
Console.WriteLine(mx.BooleanFieldString); // True
}
conststringxml=@”
T
";
使用(var stringReader=newstringreader(XML))
使用(var xmlReader=newcustomxmlreader(新列表{“BooleanField”},stringReader))
{
XmlSerializer serializer=新的XmlSerializer(typeof(MyExample));
MyExample mx=序列化程序。反序列化(xmlReader)为MyExample;
Console.WriteLine(mx.BooleanFieldString);//True
}
ConvertBooleanStringValue
返回布尔值。因此,这一行set=>_booleanField=ConvertBooleanStringValue(value)
令人困惑。只需将此方法重构为所有属性设置程序都可以调用的静态实用程序类,就可以大大降低成本。然而,仍然需要实现属性和调用方法。这里确实有问题吗?可能有点容易出错,但根据应用程序的不同,我可能会添加一个设置“允许遗留xml格式”并使用string。替换上的“FALSE”
和>FALSE您是(单独)吗负责序列化,还是需要对从您无法控制的地方获取的数据进行反序列化?
const String XML = @"
<MyExample>
<BooleanField>T</BooleanField>
</MyExample>";
using (var stringReader = new StringReader(XML))
using (var xmlReader = new CustomXmlReader(new List<String> { "BooleanField" }, stringReader))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyExample));
MyExample mx = serializer.Deserialize(xmlReader) as MyExample;
Console.WriteLine(mx.BooleanFieldString); // True
}