OpenXML SDK 3.2.0.0赋值EnumValue<T>时触发ArgumentOutOfRangeException
OpenXML SDK 3.2.0.0枚举值解析异常问题(已通过IsValid校验仍报错)
问题背景
从OpenXML SDK 2.x迁移至3.2.0.0版本时,处理TableLayout.Type这类枚举属性遇到问题:2.x版本依赖Enum.TryParse验证解析枚举值,3.x改用TableLayoutValues结构体的IsValid属性校验,但出现校验通过后构造EnumValue<T>仍抛出ArgumentOutOfRangeException的情况。
3.x版本出错代码
if (new TableLayoutValues(inputValue) is TableLayoutValues layout && ((IEnumValue)layout).IsValid) { TableLayout tableLayout = new TableLayout(); tableLayout.Type = new EnumValue<TableLayoutValues>(layout); tableProperties.AppendChild(tableLayout); }
抛出异常信息
System.ArgumentOutOfRangeException: The specified value is not valid according to the specified enum type. Parameter name: value at DocumentFormat.OpenXml.EnumValue`1.ValidateSet(T value) ...
2.x版本正常运行代码
if (Enum.TryParse(inputValue, true, out TableLayoutValues layout)) { TableLayout tableLayout = new TableLayout(); tableLayout.Type = new EnumValue<TableLayoutValues>(layout); tableProperties.AppendChild(tableLayout); }
已尝试操作
- 在赋值给
EnumValue前调用IEnumValue.IsValid验证值 - 确认
inputValue为合法枚举值(fixed、autofit) - 调试确认
inputValue完全匹配有效枚举值
核心疑问
为何3.x中通过IsValid校验的值,构造EnumValue<T>仍报错?是否误解了新版本的枚举处理机制?如何在3.x中安全解析并验证枚举值?
原因分析
OpenXML SDK 3.x的枚举结构体(如TableLayoutValues)实现了IEnumValue接口,但IsValid属性仅校验字符串是否属于合法枚举名称,而EnumValue<T>的构造方法会额外验证传入实例对应的底层枚举数值是否在定义的常量范围内。直接用new TableLayoutValues(inputValue)构造的实例,可能出现字符串合法但数值未正确映射到枚举常量的情况,导致后续EnumValue<T>校验失败。
解决方案
方案1:使用枚举结构体的静态TryParse方法
3.x的枚举结构体大多提供了静态TryParse方法,会直接返回同时具备合法字符串和对应枚举数值的实例,完全符合EnumValue<T>的要求:
if (TableLayoutValues.TryParse(inputValue, ignoreCase: true, out var layout) && layout.IsValid) { var tableLayout = new TableLayout(); tableLayout.Type = new EnumValue<TableLayoutValues>(layout); tableProperties.AppendChild(tableLayout); }
方案2:直接用字符串构造EnumValue<T>
EnumValue<T>本身支持直接传入字符串并内部完成验证,无需手动构造枚举结构体:
if (EnumValue<TableLayoutValues>.IsValidEnumString(inputValue)) { var tableLayout = new TableLayout(); tableLayout.Type = new EnumValue<TableLayoutValues>(inputValue); tableProperties.AppendChild(tableLayout); }
如果不想依赖预校验,也可以用异常捕获处理无效值场景:
try { var tableLayout = new TableLayout(); tableLayout.Type = new EnumValue<TableLayoutValues>(inputValue); tableProperties.AppendChild(tableLayout); } catch (ArgumentOutOfRangeException) { // 处理无效输入逻辑 }
内容的提问来源于stack exchange,提问作者Geringverdiener
相关产品推荐
相关产品推荐

