OrchardCMS/OrchardCore · error · InvalidCastException

Cannot convert to DateTime

Error message

Cannot convert {value} to DateTime

What it means

JsonDynamicValue wraps a JSON value and exposes explicit cast operators to .NET primitives. The explicit operator DateTime casts via JsonValueExtensions.GetValue<DateTime>(); when the cast target is null (null wrapper) or the underlying JSON value cannot be represented as a DateTime, the operator throws InvalidCastException with this message. It exists to give a clear diagnostic instead of an opaque null-reference or conversion failure.

Solutions

  1. Verify the underlying JSON token is a valid date string (e.g. ISO 8601) or JSON date before casting
  2. Use the nullable explicit operator (DateTime?)jsonDynamicValue, which returns null instead of throwing, and check for null
  3. Call GetValue on the raw JToken/JsonValue with TryGetValue-style handling or DateTime.TryParse on the string first
  4. Guard the wrapper itself for null before casting

Example fix

// before
var created = (DateTime)jsonDynamicValue["CreatedAt"];
// after
var created = (DateTime?)jsonDynamicValue["CreatedAt"] ?? DateTime.UtcNow;
Defensive patterns

Strategy: type-guard

Validate before calling

// pre-check before casting
if (jsonDynamicValue is null) throw new InvalidOperationException("null wrapper");
var raw = jsonDynamicValue.ToString();
if (!DateTime.TryParse(raw, CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
    throw new InvalidOperationException($"'{raw}' is not a DateTime");
var dt = (DateTime)jsonDynamicValue;

Type guard

static bool TryGetDateTime(JsonDynamicValue v, out DateTime value)
{
    value = default;
    if (v is null) return false;
    var dt = (DateTime?)v;
    if (dt is null) return false;
    value = dt.Value;
    return true;
}

Try / catch

DateTime dt;
try
{
    dt = (DateTime)jsonDynamicValue["CreatedAt"];
}
catch (InvalidCastException ex)
{
    // log and fall back to a sentinel/default
    dt = DateTime.MinValue;
}

Prevention

When it happens

Trigger: Executing `(DateTime)jsonDynamicValue` (via dynamic dispatch or direct cast) where the wrapper is null or its _jsonValue is null, or where the JSON token is a non-date value (plain string not parseable as DateTime, number, boolean, object, array).

Common situations: Reading JSON property bags (content item JSON, workflow inputs, query results) where a field is expected to be a date but is null, absent, or stored as an arbitrary string; schema changes that turn a date field into text; hand-edited JSON data.

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/426525b09747f346. Report an issue: GitHub.

Appendix: source

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

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

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

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

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

    public static explicit operator DateTime?(JsonDynamicValue value)
    {
        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?>();
    }

View on GitHub (pinned to 4306c0717f)