{"record":{"id":"3fbfb09450e1f7b0","repo":"OrchardCMS/OrchardCore","slug":"deserializing-a-typeof-t-name-is-not-supported","errorCode":null,"errorMessage":"Deserializing a {typeof(T).Name} is not supported.","messagePattern":"Deserializing a (.+?) is not supported\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Abstractions/Json/Serialization/JsonDynamicJsonConverter.cs","lineNumber":11,"sourceCode":"using System.Text.Json.Dynamic;\n\n#nullable enable\n\nnamespace System.Text.Json.Serialization;\n\npublic sealed class JsonDynamicJsonConverter<T> : JsonConverter<T> where T : JsonDynamicBase\n{\n    public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        throw new NotSupportedException($\"Deserializing a {typeof(T).Name} is not supported.\");\n    }\n\n    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)\n    {\n        if (value.Node != null)\n        {\n            value.Node.WriteTo(writer, options);\n        }\n        else\n        {\n            writer.WriteNullValue();\n        }\n    }\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Abstractions/Json/Serialization/JsonDynamicJsonConverter.cs#L1-L26","documentation":"JsonDynamicJsonConverter<T> intentionally throws NotSupportedException in Read because JsonDynamicBase-derived types (dynamic JSON wrappers) can only be written (serialized), never deserialized back into the typed wrapper. The converter is write-only by design: the underlying JsonNode-based value cannot be reconstructed into the original dynamic subclass. Hitting this means your code asked System.Text.Json to round-trip a type that only supports the write direction.","triggerScenarios":"Calling JsonSerializer.Deserialize<T> (or Deserialize anonymously via an API model) where T is a JsonDynamicBase-derived type registered with JsonDynamicJsonConverter<T> — e.g. deserializing a stored payload back into a JsonDynamicObject/JsonDynamicValue type.","commonSituations":"Persisting a dynamic JSON document and later trying to load it back into the same dynamic wrapper type; using the dynamic type in an API controller's [FromBody] or a deserialization-heavy path; wiring the converter globally via options.Converters.Add so accidental Deserialize calls route to it.","solutions":["Deserialize into JsonNode / JsonDocument / a plain DTO instead of the JsonDynamicBase-derived type.","Wrap deserialization in your own two-step approach: parse to JsonNode, then construct the dynamic wrapper manually if a constructor exists.","Remove the dynamic type from deserialization paths — keep it only for serialization; define a separate read model.","Audit options.Converters registrations and remove JsonDynamicJsonConverter<T> from generic global registration if it causes unintended routing.","If round-tripping is required, write your own JsonConverter<T> that parses to JsonNode and instantiates the concrete dynamic type."],"exampleFix":"// before\nvar doc = JsonSerializer.Deserialize<MyJsonDynamicObject>(json, options); // throws\n\n// after\nvar node = JsonNode.Parse(json);\nvar doc = new MyJsonDynamicObject(node); // construct manually from the parsed node","handlingStrategy":"type-guard","validationCode":"if (typeof(JsonDynamicBase).IsAssignableFrom(targetType))\n    throw new InvalidOperationException($\"{targetType.Name} is serialize-only; deserialize into JsonNode or a DTO instead.\");","typeGuard":"static bool IsDeserializable<T>() => !typeof(JsonDynamicBase).IsAssignableFrom(typeof(T));\n// guard at call site:\n// if (IsDeserializable<MyJsonDynamicObject>()) var x = JsonSerializer.Deserialize<MyJsonDynamicObject>(json);","tryCatchPattern":"try\n{\n    return JsonSerializer.Deserialize<T>(json, options);\n}\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"is not supported\"))\n{\n    var node = JsonNode.Parse(json);\n    return node is null ? null : new T(node); // construct from parsed node via your factory\n}","preventionTips":["Treat all JsonDynamicBase-derived types as write-only in your data flow.","Maintain separate read models (DTOs or JsonNode) for deserialization paths.","Never register JsonDynamicJsonConverter<T> as a global catch-all converter.","Search the codebase for Deserialize<> calls on dynamic wrapper types during reviews.","Document the one-way nature of these types near their definitions."],"tags":["json","deserialization","not-supported","system-text-json","orchardcore"],"backgroundTag":"unsupported-operation","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}