如何允许在 .NET 中使用 XmlReader 替代有效枚举值?

问题描述

我需要能够使 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 (将#修改为@)