I’m migrating code from OpenXML SDK version 2.x to 3.2.0.0 and facing an issue with EnumValue when assigning values to OpenXML elements. In version 2.x, I used Enum.TryParse to validate and parse enum values before assigning them. However, in OpenXML SDK 3.x, Enum.TryParse is no longer used for enum-like values. Instead, the library relies on structs like TableLayoutValues, which provide validation through an IsValid property.
Here’s the new implementation:
if (new TableLayoutValues(inputValue) is TableLayoutValues layout && ((IEnumValue)layout).IsValid)
{
TableLayout tableLayout = new TableLayout();
tableLayout.Type = new EnumValue<TableLayoutValues>(layout);
tableProperties.AppendChild(tableLayout);
}
This throws the following exception at runtime when creating the EnumValue:
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)
...
In version 2.x, the following code worked without issues:
if (Enum.TryParse(inputValue, true, out TableLayoutValues layout))
{
TableLayout tableLayout = new TableLayout();
tableLayout.Type = new EnumValue<TableLayoutValues>(layout);
tableProperties.AppendChild(tableLayout);
}
What I’ve Tried:
My Question:
At this point, I feel like I’ve tried everything I can think of, but I still can’t figure out why this exception is being thrown. Why does EnumValue throw an ArgumentOutOfRangeException in OpenXML SDK 3.2.0.0 even when the value passes the IsValid check? Is there something about the new version that I’m misunderstanding? How can I safely parse and validate enum values in version 3.x to avoid this exception?
After migrating to OpenXML SDK 3.x, I discovered that the behavior of EnumValue has changed significantly. Unlike in version 2.x, where you could use Enum.TryParse to dynamically validate and parse enum-like values, version 3.x requires the use of predefined static instances of the struct (e.g., TableLayoutValues.Fixed or TableLayoutValues.Autofit). This is because the SDK now enforces stricter validation, and creating new instances with the same string value is no longer supported.
For my use case, I resolved the issue by explicitly mapping the input string to the predefined static instances:
if (string.Equals(inputValue, "fixed", StringComparison.OrdinalIgnoreCase))
{
TableLayout tableLayout = new TableLayout();
tableLayout.Type = new EnumValue<TableLayoutValues>(TableLayoutValues.Fixed);
tableProperties.AppendChild(tableLayout);
}
else if (string.Equals(inputValue, "autofit", StringComparison.OrdinalIgnoreCase))
{
TableLayout tableLayout = new TableLayout();
tableLayout.Type = new EnumValue<TableLayoutValues>(TableLayoutValues.Autofit);
tableProperties.AppendChild(tableLayout);
}
Unfortunately, it’s no longer possible to dynamically convert and validate strings into EnumValue instances as you could in version 2.x. This change is due to the SDK’s stricter validation and reliance on predefined static values.