问题描述
我需要能够使 XmlReader
/XmlSerializer
准备好处理它读取的枚举的多个可能值,并将其正确转换为正确的 C# 枚举。但我不知道如何做到这一点。
考虑这个 LengthUnit 枚举(为简洁起见,仅缩减为 2 个可能的单位)
public enum LengthUnit
{
Micron,Millimeter,}
我的代码像这样写和读得很好:
<CurrentUnit>Millimeter</CurrentUnit>
但是reader 代码需要能够处理两个可能的值之一:“毫米”或“毫米”并将其正确转换为 LengthUnit.Millimeter
所以我需要能够读取以上 XML 或以下内容:
<CurrentUnit>mm</CurrentUnit>
不幸的是,当我尝试使用后者读取文件时,XmlReader 会抛出 InvalidOperationException
Exception of type: 'system.invalidOperationException' Message='Instance validation error: 'mm' is not a valid value for LengthUnit.'
我查看了 XmlEnum 属性,看看是否可以解决我的问题,但它只允许我选择一个名称。没有替代
我确实找到了 this discussion about writing alternate element names,但我似乎无法将其应用于读取不同的枚举值。
这可能吗?我该怎么办。 (如果我能弄清楚如何,我什至会编写自己的自定义 [XmlEnumAttribute2]
属性。
[编辑:每个请求的解串器代码。 ]
多个类类型派生自这个抽象类并添加它们自己的属性以在 XML 中进行序列化。我没有在这里展示其他成员。要记住的关键点是,其中一些派生类使用 LengthUnit
枚举,并且(出于与此问题无关的原因),有时这些 LengthUnit
值使用短名称而不是全名持久化。
我需要能够优雅地处理它,而且我希望能够在不逐行处理 XML 的情况下处理它。
public abstract class SettingsBaseVm<T> : BaseVm where T : SettingsBaseVm<T>,new()
{
protected static T LoadImpl(string path,ILogger logger)
{
// Handle events so partial reads still work.
try
{
var events = new XmlDeserializationEvents
{
OnUnkNownAttribute = (s,e) => logger.Warn($"UserSettings: UnkNown attribute {e.Attr.Name}"),OnUnkNownElement = (s,e) => logger.Warn($"UserSettings: UnkNown element {e.Element.Name}"),OnUnkNownNode = (s,e) => logger.Warn($"UserSettings: UnkNown node {e.Name}"),OnUnreferencedobject = (s,e) => logger.Warn($"UserSettings: Unreferencedobject")
};
using var xmlReader = XmlReader.Create(path);
xmlReader.MovetoContent();
var deserializer = new XmlSerializer(typeof(T));
var settings = deserializer.Deserialize(xmlReader,events) as T ?? throw new InvalidDataException(path);
settings.Log = logger; // So it can log errors
settings.FilePath = path;
settings.IsDirty = false;
return settings;
}
catch (Exception e) when (
e is ArgumentException ||
e is IOException ||
e is NotSupportedException ||
e is UnauthorizedAccessException ||
e is SecurityException ||
e is FormatException ||
e is XmlException
)
{
logger.Error(e);
return new T() { Log = logger,FilePath = path };
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)