Open
Description
TL;DR;
Problem: Swagger doc raises an AV on load.
Cause: Code refers to TUser
(own class) in Swagger attributes, and the unit is declared in the Implementation section. MVCFramework.pas
has its own TUser
class causing a name conflict.
Workaround: Ensure own unit is declared in Interface section (after MVCFramework).
Suggestion/comments:
- Add
Assert(Assigned(aPropType),'Something is wrong')
inTMVCSwagger.TypeKindToMVCSwagSchemaType()
- Would it be possible for
MVCFramework.TUser
to be renamed (eg.TMVCUser
) in a future release? - Otherwise identify if DMVC class is used and raise a meaningful exception message
If nothing else, hopefully this issue will remain visible for future reference.
Footnote: It took ages to find the cause! I eventually noticed a "UserName"
property while debugging which was not in my class!
Details...
Code snippet
unit RestControl.Region;
interface
uses
MVCFramework
...
type
[MVCPath(gcAPIServerRoot)]
TRestControlRegion = class(TMVCController)
[MVCSwagSummary('Regions', 'Get all users for a region', 'getUsersByRegionId')]
[MVCSwagParam(plPath, 'id', 'Region ID', ptInteger, True)]
[MVCSwagParam(plQuery, 'page', 'Page no. (0=All)', ptInteger, False, '1')]
[MVCSwagResponses(200, 'Array of Users', TUser, True)] //<<<< TUser reference
[MVCSwagResponses(404, 'Region not found', TMVCErrorResponse)]
[MVCPath(uResource + gcAPIId + '/users')]
[MVCHTTPMethod([httpGET])]
procedure GetUsersByRegionId(const id: Integer);
...
implementation
uses
Model.User // My TUser class definition. This needed to be declared in Implementation section
...
procedure TRestControlRegion.GetUsersByRegionId(const id: Integer);
var
lUser : TUser;
Swagger page load
---------------------------
Debugger Exception Notification
---------------------------
Project MyAPIServer.exe raised exception class $C0000005 with message 'c0000005 ACCESS_VIOLATION'.
---------------------------
Exception in MVCFramework.Swagger.Commons
unit MVCFramework.Swagger.Commons;
1128: class function TMVCSwagger.TypeKindToMVCSwagSchemaType(aPropType: TRttiType): TMVCSwagSchemaType;
begin
Result := stUnknown;
if aPropType.TypeKind = tkUnknown then //<<< aPropType is nil
Exit;
627: lJsonFieldClass := GetJsonFieldClass(TypeKindToMVCSwagSchemaType(lJsonFieldType));
// TypeKindToMVCSwagSchemaType() is returning nil
724: ExtractJsonSchemaFromClass($<addr>, TUser, httpGET, True);
1049: ExtractJsonSchemaFromClass(TUser, httpGET, True, False);
Metadata
Metadata
Assignees
Labels
No labels