XData + Aurelius: Swagger/OpenAPI fails when entity contains TDynamicProperties (EJsonGeneratorNotFound)

Subject: XData + Aurelius: Swagger/OpenAPI fails when entity contains TDynamicProperties (EJsonGeneratorNotFound)

Hello,

we are using Aurelius with XData, including dynamic fields via

FireDacMySqlConnection.DefineMappingSetup(TMappingExplorer.DefaultInstance);

Dynamic properties work correctly inside Aurelius ORM.
The problem occurs only when an entity containing TDynamicProperties is used as a return type in an XData service.

Example service:

function GetOrders: TObjectList<Tc_order>;

The moment Swagger/OpenAPI tries to generate the schema, XData crashes with:

Stack trace excerpt:

XData.JSchema.Generators.TJSchemaGenerators.Get
XData.JSchema.Generators.TJSchemaGenerators.ProcessRef
XData.OpenAPI.Builder.TOpenApiBuilder.BuildSchema
XData.OpenAPI.Builder.TOpenApiBuilder.Build
SwaggerDocument(...)

OpenAPI generation fails even before the service is called.


Entity example (simplified):

type
  Tc_Order = class
  private
    [XDataExcludeProperty]
    [JsonIgnore]
    FDynCon: TDynamicProperties;

    [XDataExcludeProperty]
    [JsonIgnore]
    property DynCon: TDynamicProperties read FDynCon;

    …
  end;

We tried all combinations:

  • exclude attribute on field
  • exclude attribute on property
  • exclude on both
  • remove property, leave only field
  • replace type with TValue, TObject, Variant
  • wrap the dynamic properties into another class
  • return DTO without dynamic fields

The result is always the same:
Swagger/OpenAPI generator tries to reflect TDynamicProperties = TDictionary<string, TValue>
→ and crashes on TDictionary<string, TValue>.TItem, because TValue has no JSON generator registered.

Even when both property and field are marked with [XDataExcludeProperty] and [JsonIgnore], the generator still attempts to inspect the type.


Important notes:

  • ORM functionality works fine
  • Methods execute correctly when Swagger is disabled
  • The crash happens only during OpenAPI/Swagger schema generation
  • XData attempts to generate schema for TValue, even though it is excluded

Questions:

  1. What is the correct way to completely exclude TDynamicProperties from OpenAPI/Swagger generation so XData does not inspect it at all?
  2. Is there a recommended pattern for using TDynamicProperties with XData entities?
  3. Should a custom JSON generator be registered for TValue, or is this type intentionally unsupported?
  4. Is wrapping the entity into a DTO the only supported solution, or is there a built-in mechanism to hide dynamic properties?

Minimal reproducible example:

This minimal entity is enough to trigger the error:

type
  TTestEntity = class
  private
    [XDataExcludeProperty]
    property DynCon: TDynamicProperties read FDynCon;
  end;

Calling:

function GetAll: TObjectList<TTestEntity>;

→ Immediately results in:


Any guidance on the proper way to exclude or handle TDynamicProperties in XData OpenAPI generation would be greatly appreciated.

Thank you!

Can you please send a minimal compilable project reproducing the issue?

1 Like

I'll try to have the code sample ready tomorrow or on Friday.

for_wagner_json_error.zip (2.3 MB)

This is minimal code sample. In memo are 2 URLs. Worked / Crashed
in database directory is sql dump.

i’m very sorry for late response.

Petr

Unfortunately I can't compile your application. I even tried to fix some compilation problems, but there is a gazillion of dependencies and 3rd party components (UniDac, Zeos, DevExpress and many others I don't even know what they are) so I gave up. There is even things related to visual controls which I believe are not needed at all to reproduce it.

Could you please clean it up to a minimum setup?

for_wagner_json_error_cleaned.zip (2.6 MB)

I’m very sorry. My mistake. Please try this version

Petr

Reason for the error is that your second XData server (the one that fails) is mapped to model Model2. But your service references a class that does not belong to that model.

You should add such class to model Model2 so XData can treat it as an entity:

  [Entity]
  [Table('c_order')]
  [Description('Zakázky')]
  [Model('Model2'), Model('Default')] // ADD THIS LINE
  [UniqueKey('bar_id')]
  [Id('Fid', TIdGenerator.IdentityOrSequence)]
  Tc_order = class(TTMSAGObject)

Thanks, Wagner.

I've been suspecting the whole time that it would be an absolutely stupid problem.
We understand it now.

Thanks Petr

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.