如何解决在XML反序列化中将空字符串处理为Null
|| 关于这个问题,我有同样的问题。我正在使用基于SOAP的API来回发送数据,其中响应未完全遵循标准,特别是使用null值。对于“ 0”,API将发送回一个空字符串,如下所示:<nextreview></nextreview>
这会导致反序列化时发生以下错误:
字符串\'\'不是有效的AllXsd值。
所以我的想法是创建一个自定义的Nullable类型NullableOrEmpty<T>
,实现实现将空字符串转换为null的IXMLSerializable
。问题是我只想处理空字符串的特殊情况。我想使用\'default \'行为正常进行序列化和反序列化的所有其他操作。如何在下面的代码中模拟序列化的默认行为?
public class NullableOrEmpty<T> : IXmlSerializable
where T : struct
{
public T? NullableValue { get; set; }
public T Value { get { return this.NullableValue.Value; } }
public bool HasValue { get { return this.NullableValue.HasValue; } }
...
public void ReadXml(XmlReader reader)
{
string xml = reader.ReadElementContentAsString();
if (string.IsNullOrEmpty(xml))
{
this.NullableValue = null;
}
else
{
//THIS SHOULD DO THE DEFAULT. THIS DOESN\'T WORK. WHAT DO I DO??
//this.NullableValue = (T?)new XmlSerializer(typeof(T?)).Deserialize(reader);
}
}
public void WriteXml(XmlWriter writer)
{
//THIS SHOULD DO THE DEFAULT. THIS DOESN\'T WORK. WHAT DO I DO??
//new XmlSerializer(typeof(T?)).Serialize(writer,this.NullableValue);
}
}
当我说“这不起作用”时,它专门生成以下错误消息,可能是因为它试图消耗不存在的东西:
XML文档中存在错误(63,
6)。
<lastreview xmlns=\'\'>
不是
预期。
这是该处的一小段XML。该错误是由birthdate
中的值引起的,因为在实际给出该值的非异常情况下,我没有正确使用它:
<udf4></udf4>
<udf3></udf3>
<birthdate>1978-05-24Z</birthdate>
<lastreview></lastreview>
<fulltime>1</fulltime>
任何想法或想法都值得赞赏。如果需要,我可以发布更多代码示例或测试建议。谢谢!
解决方法
您可以在这里做一件事,尽管可能更麻烦的是实现适配器模式,在该模式中,您从xml结果填充的对象仅具有字符串类型的属性,然后编写一个转换器方法来填充您的\'real \ '对象,当目标属性为DateTime时检查空字符串。这可能比实现自己的序列化器容易。
,我不再使用此类(我需要第三者进行验证),但是实际上我可以通过使用
XmlConvert
帮助程序手动处理所有数据类型来使其工作:
public void ReadXml(XmlReader reader)
{
string xml = reader.ReadElementContentAsString();
if (string.IsNullOrEmpty(xml))
{
this.NullableValue = null;
}
else
{
if (this.NullableValue is bool)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToBoolean(xml),typeof(T?));
else if (this.NullableValue is byte)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToByte(xml),typeof(T?));
else if (this.NullableValue is char)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToChar(xml),typeof(T?));
else if (this.NullableValue is DateTime)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToDateTime(xml),typeof(T?));
else if (this.NullableValue is decimal)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToDecimal(xml),typeof(T?));
else if (this.NullableValue is double)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToDouble(xml),typeof(T?));
else if (this.NullableValue is Guid)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToGuid(xml),typeof(T?));
else if (this.NullableValue is short)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToInt16(xml),typeof(T?));
else if (this.NullableValue is int)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToInt32(xml),typeof(T?));
else if (this.NullableValue is long)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToInt64(xml),typeof(T?));
else if (this.NullableValue is float)
this.NullableValue = (T?)Convert.ChangeType(XmlConvert.ToSingle(xml),typeof(T?));
}
}
public void WriteXml(XmlWriter writer)
{
new XmlSerializer(typeof(T?)).Serialize(writer,this.NullableValue);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。