OrchardCMS/OrchardCore · error · InvalidCastException
Cannot convert to Decimal
Error message
Cannot convert {value} to Decimal What it means
The explicit operator decimal on JsonDynamicValue converts the wrapped JSON value with GetValue<decimal>() and throws InvalidCastException when conversion yields null or the JSON token is not numeric-decimal-compatible. It provides a descriptive message rather than letting the JSON library surface a vaguer failure.
Solutions
- Confirm the JSON token is a JSON number (or an invariant numeric string accepted by the JSON parser)
- Use the nullable cast (decimal?) and coalesce/handle null
- Convert explicitly with decimal.TryParse(value.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out var d) when values may be numeric strings
- Null-check the wrapper before casting
Example fix
// before var price = (decimal)jsonDynamicValue["Price"]; // after var price = (decimal?)jsonDynamicValue["Price"] ?? 0m;
Defensive patterns
Strategy: type-guard
Validate before calling
if (jsonDynamicValue is null) throw new InvalidOperationException("null wrapper");
var raw = jsonDynamicValue.ToString();
if (!decimal.TryParse(raw, NumberStyles.Number, CultureInfo.InvariantCulture, out _))
throw new InvalidOperationException($"'{raw}' is not a decimal");
var d = (decimal)jsonDynamicValue; Type guard
static bool TryGetDecimal(JsonDynamicValue v, out decimal value)
{
value = default;
if (v is null) return false;
var d = (decimal?)v;
if (d is null) return false;
value = d.Value;
return true;
} Try / catch
decimal amount;
try
{
amount = (decimal)jsonDynamicValue["Price"];
}
catch (InvalidCastException ex)
{
amount = 0m;
} Prevention
- Store numbers as JSON numbers, not formatted strings
- Use InvariantCulture when converting numeric strings manually
- Use (decimal?) when null is acceptable
- Validate numeric fields at ingestion time
When it happens
Trigger: Executing `(decimal)jsonDynamicValue` where the wrapper/_jsonValue is null, or the token is a non-numeric string, boolean, object, or array (numbers stored as strings also fail).
Common situations: Money/quantity fields in JSON content that are null, empty strings, or strings like "12,50" with locale-specific formatting; columns that changed from number to string in stored JSON; dynamic query results.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot convert to DateTime
- Cannot convert to DateTimeOffset
- Cannot convert to Double
- Cannot convert to Guid
- Cannot convert to
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/2f0083c1bb25a667.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:329
{
return value?._jsonValue?.GetValue<DateTime?>();
}
public static explicit operator DateTimeOffset(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<DateTimeOffset>()
?? throw new InvalidCastException($"Cannot convert {value} to DateTimeOffset");
}
public static explicit operator DateTimeOffset?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<DateTimeOffset?>();
}
public static explicit operator decimal(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<decimal>()
?? throw new InvalidCastException($"Cannot convert {value} to Decimal");
}
public static explicit operator decimal?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<decimal?>();
}
public static explicit operator double(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<double>()
?? throw new InvalidCastException($"Cannot convert {value} to Double");
}
public static explicit operator double?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<double?>();
}
View on GitHub (pinned to 4306c0717f)