diff --git a/ideexpert/DMVC.Expert.CodeGen.Commands.pas b/ideexpert/DMVC.Expert.CodeGen.Commands.pas index ed72a8ce..7324c4c3 100644 --- a/ideexpert/DMVC.Expert.CodeGen.Commands.pas +++ b/ideexpert/DMVC.Expert.CodeGen.Commands.pas @@ -316,7 +316,14 @@ begin .AppendLine('interface') .AppendLine .AppendLine('uses') - .AppendLine(' MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons, System.Generics.Collections;') + .Append(' MVCFramework, MVCFramework.Commons, '); + if Model.B[TConfigKey.entity_generate] then + begin + Section.Append('MVCFramework.Nullables, '); + end; + + Section + .AppendLine('MVCFramework.Serializer.Commons, System.Generics.Collections;') .AppendLine .AppendLine('type') end; @@ -337,9 +344,10 @@ begin inherited; if not Model.B[TConfigKey.entity_generate] then Exit; Section - .AppendLine('constructor ' + Model[TConfigKey.entity_classname] + '.Create(FirstName, LastName: String; DOB: TDate);') + .AppendLine('constructor ' + Model[TConfigKey.entity_classname] + '.Create(ID: Integer; FirstName, LastName: String; DOB: TDate);') .AppendLine('begin') .AppendLine(' inherited Create;') + .AppendLine(' fID := ID;') .AppendLine(' fFirstName := FirstName;') .AppendLine(' fLastName := LastName;') .AppendLine(' fDOB := DOB;') @@ -359,14 +367,16 @@ begin .AppendLine(' [MVCNameCase(ncCamelCase)]') .AppendLine(' ' + Model[TConfigKey.entity_classname] + ' = class') .AppendLine(' private') + .AppendLine(' fID: NullableInt32;') .AppendLine(' fFirstName: String;') .AppendLine(' fLastName: String;') .AppendLine(' fDOB: TDate;') .AppendLine(' public') + .AppendLine(' property ID: NullableInt32 read fID write fID;') .AppendLine(' property FirstName: String read fFirstName write fFirstName;') .AppendLine(' property LastName: String read fLastName write fLastName;') .AppendLine(' property DOB: TDate read fDOB write fDOB; ') - .AppendLine(' constructor Create(FirstName, LastName: String; DOB: TDate);') + .AppendLine(' constructor Create(ID: Integer; FirstName, LastName: String; DOB: TDate);') .AppendLine(' end;') .AppendLine end; @@ -435,16 +445,16 @@ begin Section .AppendLine .AppendLine('//Sample CRUD Actions for a "People" entity') - .AppendLine('function ' + Model[TConfigKey.controller_classname] + '.GetPeople: TObjectList;') + .AppendLine('function ' + Model[TConfigKey.controller_classname] + '.GetPeople: IMVCResponse;') .AppendLine('var') .AppendLine(' lPeople: TObjectList;') .AppendLine('begin') .AppendLine(' lPeople := TObjectList.Create(True);') .AppendLine(' try') - .AppendLine(' lPeople.Add(TPerson.Create(''Peter'',''Parker'', EncodeDate(1965, 10, 4)));') - .AppendLine(' lPeople.Add(TPerson.Create(''Bruce'',''Banner'', EncodeDate(1945, 9, 6)));') - .AppendLine(' lPeople.Add(TPerson.Create(''Reed'',''Richards'', EncodeDate(1955, 3, 7)));') - .AppendLine(' Result := lPeople;') + .AppendLine(' lPeople.Add(TPerson.Create(1, ''Peter'',''Parker'', EncodeDate(1965, 10, 4)));') + .AppendLine(' lPeople.Add(TPerson.Create(2, ''Bruce'',''Banner'', EncodeDate(1945, 9, 6)));') + .AppendLine(' lPeople.Add(TPerson.Create(3, ''Reed'',''Richards'', EncodeDate(1955, 3, 7)));') + .AppendLine(' Result := OkResponse(lPeople);') .AppendLine(' except') .AppendLine(' lPeople.Free;') .AppendLine(' raise;') @@ -452,40 +462,26 @@ begin .AppendLine('end;') .AppendLine .AppendLine('function ' + Model[TConfigKey.controller_classname] + '.GetPerson(ID: Integer): TPerson;') - .AppendLine('var') - .AppendLine(' lPeople: TObjectList;') .AppendLine('begin') - .AppendLine(' lPeople := GetPeople;') - .AppendLine(' try') - .AppendLine(' Result := lPeople.ExtractAt(ID mod lPeople.Count);') - .AppendLine(' finally') - .AppendLine(' lPeople.Free;') - .AppendLine(' end;') + .AppendLine(' Result := TPerson.Create(ID, ''Daniele'', ''Teti'', EncodeDate(1979, 11, 4));') .AppendLine('end;') .AppendLine .AppendLine('function ' + Model[TConfigKey.controller_classname] + '.CreatePerson([MVCFromBody] Person: TPerson): IMVCResponse;') .AppendLine('begin') .AppendLine(' LogI(''Created '' + Person.FirstName + '' '' + Person.LastName);') - .AppendLine(' Result := MVCResponseBuilder') - .AppendLine(' .StatusCode(HTTP_STATUS.Created)') - .AppendLine(' .Body(''Person created'')') - .AppendLine(' .Build;') + .AppendLine(' Result := CreatedResponse('''', ''Person created'');') .AppendLine('end;') .AppendLine .AppendLine('function ' + Model[TConfigKey.controller_classname] + '.UpdatePerson(ID: Integer; [MVCFromBody] Person: TPerson): IMVCResponse;') .AppendLine('begin') .AppendLine(' LogI(''Updated '' + Person.FirstName + '' '' + Person.LastName);') - .AppendLine(' Result := MVCResponseBuilder') - .AppendLine(' .StatusCode(HTTP_STATUS.NoContent)') - .AppendLine(' .Build;') + .AppendLine(' Result := NoContentResponse();') .AppendLine('end;') .AppendLine .AppendLine('function ' + Model[TConfigKey.controller_classname] + '.DeletePerson(ID: Integer): IMVCResponse;') .AppendLine('begin') .AppendLine(' LogI(''Deleted person with id '' + ID.ToString);') - .AppendLine(' Result := MVCResponseBuilder') - .AppendLine(' .StatusCode(HTTP_STATUS.NoContent)') - .AppendLine(' .Build;') + .AppendLine(' Result := NoContentResponse();') .AppendLine('end;') end; @@ -516,10 +512,12 @@ begin .AppendLine(' [MVCPath]') .AppendLine(' [MVCHTTPMethod([httpGET])]') .AppendLine(' function Index: String;') + .AppendLine .AppendLine(' [MVCPath(''/reversedstrings/($Value)'')]') .AppendLine(' [MVCHTTPMethod([httpGET])]') .AppendLine(' [MVCProduces(TMVCMediaType.TEXT_PLAIN)]') .AppendLine(' function GetReversedString(const Value: String): String;') + .AppendLine end; if Model.B[TConfigKey.controller_crud_methods_generate] then @@ -533,16 +531,20 @@ begin .AppendLine(' //Sample CRUD Actions for a "People" entity') .AppendLine(' [MVCPath(''/people'')]') .AppendLine(' [MVCHTTPMethod([httpGET])]') - .AppendLine(' function GetPeople: TObjectList;') + .AppendLine(' function GetPeople: IMVCResponse;') + .AppendLine .AppendLine(' [MVCPath(''/people/($ID)'')]') .AppendLine(' [MVCHTTPMethod([httpGET])]') .AppendLine(' function GetPerson(ID: Integer): TPerson;') + .AppendLine .AppendLine(' [MVCPath(''/people'')]') .AppendLine(' [MVCHTTPMethod([httpPOST])]') .AppendLine(' function CreatePerson([MVCFromBody] Person: TPerson): IMVCResponse;') + .AppendLine .AppendLine(' [MVCPath(''/people/($ID)'')]') .AppendLine(' [MVCHTTPMethod([httpPUT])]') .AppendLine(' function UpdatePerson(ID: Integer; [MVCFromBody] Person: TPerson): IMVCResponse;') + .AppendLine .AppendLine(' [MVCPath(''/people/($ID)'')]') .AppendLine(' [MVCHTTPMethod([httpDELETE])]') .AppendLine(' function DeletePerson(ID: Integer): IMVCResponse;') @@ -921,9 +923,10 @@ begin if not Model.B[TConfigKey.entity_generate] then Exit; CheckFor(TConfigKey.entity_classname, Model); Section - .AppendLine('constructor ' + Model[TConfigKey.entity_classname] + '.Create(FirstName, LastName: String; DOB: TDate);') + .AppendLine('constructor ' + Model[TConfigKey.entity_classname] + '.Create(ID: Integer; FirstName, LastName: String; DOB: TDate);') .AppendLine('begin') .AppendLine(' inherited Create;') + .AppendLine(' fID := ID;') .AppendLine(' fFirstName := FirstName;') .AppendLine(' fLastName := LastName;') .AppendLine(' fDOB := DOB;') diff --git a/ideexpert/DMVC.Expert.Commons.pas b/ideexpert/DMVC.Expert.Commons.pas index 5f0e7c89..6527c645 100644 --- a/ideexpert/DMVC.Expert.Commons.pas +++ b/ideexpert/DMVC.Expert.Commons.pas @@ -107,8 +107,8 @@ begin lFileName := TPath.GetFileNameWithoutExtension(IOTA.FileName); lFileExt := TPath.GetExtension(IOTA.FileName); lFileName := FileNamePrefix; - IOTA.FileName := TPath.Combine(lDirName, lFileName + lFileExt); - IOTA.Refresh(False); +// IOTA.FileName := TPath.Combine(lDirName, lFileName + lFileExt); +// IOTA.Refresh(False); end; end. diff --git a/ideexpert/DMVC.Expert.Forms.NewProjectWizard.pas b/ideexpert/DMVC.Expert.Forms.NewProjectWizard.pas index 386704ef..e1d26494 100644 --- a/ideexpert/DMVC.Expert.Forms.NewProjectWizard.pas +++ b/ideexpert/DMVC.Expert.Forms.NewProjectWizard.pas @@ -316,8 +316,8 @@ begin fModel.B[TConfigKey.entity_generate] := fModel.B[TConfigKey.controller_crud_methods_generate]; fModel.S[TConfigKey.entity_classname] := 'TPerson'; fModel.B[TConfigKey.jsonrpc_generate] := GetCreateJSONRPCInterface; - fModel.S[TConfigKey.jsonrpc_classname] := GetJSONRPCClassName; - fModel.S[TConfigKey.jsonrpc_unit_name] := 'TBA'; + fModel.S[TConfigKey.jsonrpc_classname] := GetJSONRPCClassName; + fModel.S[TConfigKey.jsonrpc_unit_name] := 'TBA'; //webmodule diff --git a/samples/articles_crud_server/articles_crud_server.dpr b/samples/articles_crud_server/articles_crud_server.dpr index bb0aeeae..6688f22e 100644 --- a/samples/articles_crud_server/articles_crud_server.dpr +++ b/samples/articles_crud_server/articles_crud_server.dpr @@ -78,7 +78,7 @@ begin CreateFirebirdPrivateConnDef(True); DefaultMVCServiceContainer - .RegisterType(TArticlesService, IArticlesService, '', TRegistrationType.SingletonPerRequest) + .RegisterType(TArticlesService, IArticlesService, TRegistrationType.SingletonPerRequest) .Build; WebRequestHandlerProc.MaxConnections := dotEnv.Env('dmvc.handler.max_connections', 1024); diff --git a/samples/custom_exception_handling/custom_exception_handling.dproj b/samples/custom_exception_handling/custom_exception_handling.dproj index bbc2ad7b..0febea3f 100644 --- a/samples/custom_exception_handling/custom_exception_handling.dproj +++ b/samples/custom_exception_handling/custom_exception_handling.dproj @@ -1,7 +1,7 @@  {EDD78707-A0BE-4217-9B4E-919CCEDF5CF6} - 19.2 + 20.1 VCL custom_exception_handling.dpr True @@ -9,25 +9,11 @@ Win32 1 Console + custom_exception_handling true - - true - Base - true - - - true - Base - true - - - true - Base - true - true Base @@ -73,34 +59,6 @@ 5129 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - - DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) - android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - true - Base - true - DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage);$(DCC_UsePackage) - android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - - - DataSnapServerMidas;FireDACADSDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;inetdb;emsedge;IndyCore;dsnap;DataSnapCommon;DataSnapConnectors;bindengine;FireDACOracleDriver;FireDACMySQLDriver;FireDACCommonODBC;DataSnapClient;IndySystem;FireDACDb2Driver;FireDACInfxDriver;emshosting;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;DbxCommonDriver;DataSnapServer;xmlrtl;DataSnapNativeClient;rtl;DbxClientDriver;CustomIPTransport;bindcomp;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;$(DCC_UsePackage) - DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;pfmgrPkgDXE11;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;TMSCryptoPkgDXE11;FmxTeeUI;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;pfcorePkgDXE11;FixInsight_10_2;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TMSFMXCloudPackPkgDXE11;TeeDB;emshosting;TMSFMXWebGMapsPkgDXE11;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;TMSFMXCloudPackPkgDEDXE11;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;TMSFMXPackPkgDXE11;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;TMSCryptoPkgDEDXE11;fmxase;$(DCC_UsePackage) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) @@ -139,10 +97,6 @@
MyWebModule
TWebModule - - Cfg_2 - Base - Base @@ -150,6 +104,10 @@ Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -164,33 +122,12 @@ Microsoft Office XP Sample Automation Server Wrapper Components - - - - true - - - - - true - - - - - true - - - - - true - - - - - custom_exception_handling.exe - true - - + + + + + + 1 @@ -199,14 +136,14 @@ 0 - + classes - 1 + 64 classes - 1 + 64 @@ -219,12 +156,6 @@ 1 - - - library\lib\armeabi-v7a - 1 - - library\lib\armeabi @@ -277,6 +208,16 @@ 1 + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + res\values @@ -297,6 +238,66 @@ 1 + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + res\values @@ -307,6 +308,16 @@ 1 + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + res\drawable @@ -477,6 +488,56 @@ 1 + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + 1 @@ -497,6 +558,10 @@ 1 .framework + + 1 + .framework + 0 @@ -510,6 +575,10 @@ 1 .dylib + + 1 + .dylib + 0 .dll;.bpl @@ -524,7 +593,7 @@ 1 .dylib - + 1 .dylib @@ -536,6 +605,10 @@ 1 .dylib + + 1 + .dylib + 0 .bpl @@ -554,7 +627,7 @@ 0 - + 0 @@ -563,512 +636,11 @@ 0 - + 0 - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 + + 0 @@ -1079,31 +651,6 @@ 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - - 1 - - - 1 - - - 1 - - @@ -1116,6 +663,10 @@ Contents\Resources 1 + + Contents\Resources + 1 + @@ -1132,7 +683,7 @@ 1 - + 1 @@ -1144,6 +695,9 @@ 1 + + 1 + 0 @@ -1161,6 +715,37 @@ 1 + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + @@ -1182,21 +767,221 @@ 1 - - - - - - + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + - - + + + + + + + + + + + - False - False - False True False diff --git a/samples/renders/RenderSampleControllerU.pas b/samples/renders/RenderSampleControllerU.pas index 44473c50..6fcfb7a1 100644 --- a/samples/renders/RenderSampleControllerU.pas +++ b/samples/renders/RenderSampleControllerU.pas @@ -34,7 +34,7 @@ uses MVCFramework.Serializer.Intf, System.Rtti, System.Generics.Collections, - BusinessObjectsU, Data.DB; + BusinessObjectsU, Data.DB, System.Classes, System.SysUtils; type @@ -64,10 +64,15 @@ type [MVCProduces('text/plain')] function GetPerson_AsText_AsFunction(const ID: Integer): String; + [MVCHTTPMethod([httpGET])] + [MVCPath('/func/customers.csv')] + function GetPeopleAsCSV_AsFunction: String; + + // this action is polymorphic [MVCHTTPMethod([httpGET])] [MVCPath('/func/skilledpeople')] - [MVCProduces('application/json')] + //[MVCProduces('application/json')] function GetProgrammersAndPhilosophersAsObjectList_AsFunction: TObjectList; [MVCHTTPMethod([httpGET])] @@ -294,8 +299,6 @@ uses MVCFramework.Logger, MyDataModuleU, System.IOUtils, - System.Classes, - System.SysUtils, WebModuleU, CustomTypesU, InMemoryDataU, @@ -962,6 +965,23 @@ begin RenderResponseStream; end; +function TRenderSampleController.GetPeopleAsCSV_AsFunction: String; +var + lSS: TStringBuilder; +begin + ContentType := TMVCMediaType.TEXT_CSV; + lSS := TStringBuilder.Create(''); + try + lSS.AppendLine('first_name;last_name;age'); + lSS.AppendLine('Daniele;Teti;38'); + lSS.AppendLine('Peter;Parker;22'); + lSS.AppendLine('Bruce;Banner;60'); + Result := lSS.ToString; + finally + lSS.Free; + end; +end; + procedure TRenderSampleController.GetPeopleWithTiming; var p: TPerson; @@ -1164,7 +1184,6 @@ end; procedure TRenderSampleController.GetPersonPhoto; begin - // ContentType := 'image/jpeg'; SendFile('..\..\_\customer.png'); end; diff --git a/samples/simple_api_using_mvcactiverecord/SimpleRESTAPIUsingActiveRecord.dproj b/samples/simple_api_using_mvcactiverecord/SimpleRESTAPIUsingActiveRecord.dproj index 0aa29aa1..3bda7ff9 100644 --- a/samples/simple_api_using_mvcactiverecord/SimpleRESTAPIUsingActiveRecord.dproj +++ b/samples/simple_api_using_mvcactiverecord/SimpleRESTAPIUsingActiveRecord.dproj @@ -1,7 +1,7 @@  {2921E3FB-91B6-4BA4-A930-D3F18FEED6C6} - 19.5 + 20.1 None SimpleRESTAPIUsingActiveRecord.dpr True @@ -9,30 +9,11 @@ Win32 1 Console + SimpleRESTAPIUsingActiveRecord true - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - true Base @@ -77,48 +58,6 @@ 1040 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - - DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;ibxbindings;rtl;DbxClientDriver;FireDACDSDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) - android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - true - Base - true - DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;ibxbindings;rtl;DbxClientDriver;FireDACDSDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage);$(DCC_UsePackage) - android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - - - iPhoneAndiPad - true - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2x.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImageDark_2x.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_3x.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImageDark_3x.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SettingIcon_58x58.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_SettingIcon_87x87.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png - $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png - $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png - $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png - $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImage_2x.png - $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageDark_2x.png - $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png - $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png - $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png - - - RESTComponents;DataSnapServerMidas;emsclientfiredac;DataSnapFireDAC;FireDACADSDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;inetdb;emsedge;FireDACIBDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;soapserver;bindengine;FireDACOracleDriver;CloudService;FireDACMySQLDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndySystem;FireDACDb2Driver;FireDACInfxDriver;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;rtl;emsserverresource;DbxClientDriver;CustomIPTransport;bindcomp;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;$(DCC_UsePackage) - DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;emsserverresource;DbxClientDriver;FireDACDSDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dmvcframeworkRT;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dmvcframeworkDT;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) @@ -289,6 +228,16 @@ 1 + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + res\values @@ -309,6 +258,66 @@ 1 + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + res\values @@ -319,6 +328,16 @@ 1 + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + res\drawable @@ -489,6 +508,56 @@ 1 + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + 1 @@ -594,6 +663,130 @@ 0 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset @@ -794,127 +987,6 @@ 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - 1 - - - 1 - - - 1 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - @@ -927,12 +999,9 @@ + - False - False - False - False True False diff --git a/sources/MVCFramework.Router.pas b/sources/MVCFramework.Router.pas index 51d71ac3..add33c8a 100644 --- a/sources/MVCFramework.Router.pas +++ b/sources/MVCFramework.Router.pas @@ -44,11 +44,13 @@ type private FValue: string; FParams: TList; + FRegEx: TRegEx; public constructor Create(aValue: string; aParams: TList); virtual; destructor Destroy; override; function Value: string; function Params: TList; // this should be read-only... + function Match(const Value: String): TMatch; inline; end; TMVCRouter = class(TMVCCustomRouter) @@ -356,13 +358,18 @@ function TMVCRouter.IsCompatiblePath( end; var - lRegEx: TRegEx; +// lRegEx: TRegEx; lMatch: TMatch; lPattern: string; I: Integer; lNames: TList; lCacheItem: TMVCActionParamCacheItem; begin + if (APath = AMVCPath) or ((APath = '/') and (AMVCPath = '')) then + begin + Exit(True); + end; + if not FActionParamsCache.TryGetValue(AMVCPath, lCacheItem) then begin lNames := GetParametersNames(AMVCPath); @@ -371,19 +378,16 @@ begin FActionParamsCache.Add(AMVCPath, lCacheItem); end; - if (APath = AMVCPath) or ((APath = '/') and (AMVCPath = '')) then - Exit(True) - else +// lRegEx := TRegEx.Create(lCacheItem.Value, [roIgnoreCase, roCompiled, roSingleLine]); +// lMatch := lRegEx.Match(APath); + + lMatch := lCacheItem.Match(APath); + Result := lMatch.Success; + if Result then begin - lRegEx := TRegEx.Create(lCacheItem.Value, [roIgnoreCase, roCompiled, roSingleLine]); - lMatch := lRegEx.Match(APath); - Result := lMatch.Success; - if Result then + for I := 1 to Pred(lMatch.Groups.Count) do begin - for I := 1 to Pred(lMatch.Groups.Count) do - begin - aParams.Add(lCacheItem.Params[I - 1], TIdURI.URLDecode(lMatch.Groups[I].Value)); - end; + aParams.Add(lCacheItem.Params[I - 1], TIdURI.URLDecode(lMatch.Groups[I].Value)); end; end; end; @@ -534,6 +538,7 @@ begin inherited Create; FValue := aValue; FParams := aParams; + FRegEx := TRegEx.Create(FValue, [roIgnoreCase, roCompiled, roSingleLine]); end; destructor TMVCActionParamCacheItem.Destroy; @@ -542,6 +547,11 @@ begin inherited; end; +function TMVCActionParamCacheItem.Match(const Value: String): TMatch; +begin + Result := fRegEx.Match(Value); +end; + function TMVCActionParamCacheItem.Params: TList; begin Result := FParams; diff --git a/sources/MVCFramework.pas b/sources/MVCFramework.pas index 19da60b5..3ddf2413 100644 --- a/sources/MVCFramework.pas +++ b/sources/MVCFramework.pas @@ -775,13 +775,13 @@ type /// https://restfulapi.net/http-status-202-accepted/ /// procedure Render202Accepted(const HREF: string; const ID: string; - const Reason: string = 'Accepted'); virtual; deprecated; + const Reason: string = 'Accepted'); virtual; /// /// HTTP Status 204 (No Content) indicates that the server has successfully fulfilled the request and that there is no content to send in the response payload body. The server might want to return updated meta information in the form of entity-headers, which if present SHOULD be applied to current document’s active view if any. /// The 204 response MUST NOT include a message-body and thus is always terminated by the first empty line after the header fields. /// procedure Render204NoContent(const Location: string = ''; - const Reason: string = ''); virtual; deprecated; + const Reason: string = ''); virtual; @@ -3229,17 +3229,21 @@ begin // From now on we'll check for url mapped parameters if not AContext.Request.SegmentParam(lParamName, lStrValue) then + begin raise EMVCException.CreateFmt(http_status.BadRequest, 'Invalid parameter %s for action %s (Hint: Here parameters names are case-sensitive)', [lParamName, AActionName]); + end; AActualParams[I] := GetActualParam(AActionFormalParams[I], lStrValue); end; if (AContext.Request.SegmentParamsCount + lAttributeInjectedParamCount) <> Length(AActionFormalParams) then + begin raise EMVCException.CreateFmt(http_status.BadRequest, 'Parameters count mismatch (expected %d actual %d) for action "%s"', [Length(AActionFormalParams), AContext.Request.SegmentParamsCount, AActionName]); + end; end; procedure TMVCEngine.FixUpWebModule;