OrchardCMS/OrchardCore · error · InvalidCastException

Cannot convert to Float

Error message

Cannot convert {value} to Float

What it means

JsonDynamicValue wraps a JSON value and exposes explicit conversion operators for primitive types. The explicit operator float casts _jsonValue.GetValue<float>(); if the underlying JSON value is absent, null, or not representable as a single-precision float, the operator returns null and throws InvalidCastException with 'Cannot convert {value} to Float'. It signals that the requested numeric conversion is not possible for the wrapped JSON token.

Solutions

  1. Cast to float? (explicit operator float?) instead of float, which returns null instead of throwing, then handle the null case.
  2. Validate the JSON value with TryGetValue/GetValue and confirm it is a number before casting.
  3. If the JSON stores the number as a string, parse it explicitly (float.TryParse with the right CultureInfo) instead of casting.
  4. Wrap the cast in try/catch for InvalidCastException if the value is genuinely optional.

Example fix

// before
float ratio = (float)jsonValue; // throws when jsonValue is "1.5" (string)

// after
float? ratio = (float?)jsonValue;
if (ratio is null) { /* handle missing/invalid value */ }
Defensive patterns

Strategy: type-guard

Validate before calling

if (jsonValue is null || (jsonValue.Type != JTokenType.Float && jsonValue.Type != JTokenType.Integer))
    throw new InvalidOperationException("Expected a numeric JSON value for float cast.");

Type guard

static bool IsConvertibleToFloat(JsonDynamicValue v) =>
    v?._jsonValue is { Type: JTokenType.Float or JTokenType.Integer };

Try / catch

try
{
    float f = (float)jsonValue;
}
catch (InvalidCastException ex)
{
    // log and fall back to a default or skip the record
    float f = default;
}

Prevention

When it happens

Trigger: Casting a JsonDynamicValue instance to float with (float)jsonDynamicValue when the wrapped JSON token is null, not a number (e.g. a JSON string "1.5"), or a number Json.NET cannot convert to float, causing GetValue<float>() to yield null.

Common situations: Reading measurement fields stored as strings in JSON, casting on a JsonDynamicValue constructed from a null/default _jsonValue, or locale/producer differences where decimal values are serialized as strings instead of numbers.

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


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/cb0f28d32e5881d4. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:406

    {
        return value?._jsonValue?.GetValue<long?>();
    }

    public static explicit operator sbyte(JsonDynamicValue value)
    {
        return value?._jsonValue?.GetValue<sbyte>()
            ?? throw new InvalidCastException($"Cannot convert {value} to SByte");
    }

    public static explicit operator sbyte?(JsonDynamicValue value)
    {
        return value?._jsonValue?.GetValue<sbyte?>();
    }

    public static explicit operator float(JsonDynamicValue value)
    {
        return value?._jsonValue?.GetValue<float>()
            ?? throw new InvalidCastException($"Cannot convert {value} to Float");
    }

    public static explicit operator float?(JsonDynamicValue value)
    {
        return value?._jsonValue?.GetValue<float?>();
    }

    public static explicit operator string?(JsonDynamicValue value)
    {
        return value?.ToString();
    }

    public static explicit operator ushort(JsonDynamicValue value)
    {
        return value?._jsonValue?.GetValue<ushort>()
            ?? throw new InvalidCastException($"Cannot convert {value} to UInt32");
    }

View on GitHub (pinned to 4306c0717f)