TMVCEngine.Config property is now read-only. Can be changed only in the anonymous method injected in the constructor. (All the samples have been updated - from an idea of @Spinettato a.k.a. Danielino)

This commit is contained in:
Daniele Teti 2020-05-11 23:39:43 +02:00
parent a5c4f31dfa
commit 028089969a
28 changed files with 732 additions and 192 deletions

4
.angulardoc.json Normal file
View File

@ -0,0 +1,4 @@
{
"repoId": "597fc48e-dd8a-489c-9aa4-175e8fd8d673",
"lastSync": 0
}

View File

@ -4,4 +4,5 @@
- `TDataSetHolder` class now renders data in a property called `data` (previously was `items`)
- The default header used by JWT middleware is now `Authorization` (previously was `Authentication`)
- Middleware `OnAfterControllerAction` are now invoked in the same order of `OnBeforeControllerAction` (previously were invoked in reversed order).
- `IMVCMiddleware` has got a new method called after the request processing: `OnAfterRouting` . It is called even if no action is executed. If you don't need it, implement the method and leave it empty.
- `IMVCMiddleware` has got a new method called after the request processing: `OnAfterRouting` . It is called even if no action is executed. If you don't need it, implement the method and leave it empty.
- `TMVCEngine` is no more responsible for static file serviing. If you need static files used the new `TMVCStaticFilesMiddleware` (check the sample).

View File

@ -370,39 +370,23 @@ begin
end;
```
- New! Custom Exception Handling (Based on work of [David Moorhouse](https://github.com/fastbike)). Sample "custom_exception_handling" show how to use it.
- Improved! Exceptions rendering while using MIME types different to `application/json`.
- SSL Server support for `TMVCListener` (Thanks to [Sven Harazim](https://github.com/landrix))
- Improved! Datasets serialization speed improvement. In some case the performance [improves of 2 order of magnitude](https://github.com/danieleteti/delphimvcframework/issues/205#issuecomment-479513158). (Thanks to https://github.com/pedrooliveira01)
- New! Added `in` operator in RQL parser (Thank you to [João Antônio Duarte](https://github.com/joaoduarte19) for his initial work on this)
- New! Added `TMVCActiveRecord.Count<T>(RQL)` to count record based on RQL criteria
- New! `TMVCActiveRecord` can handle non autogenerated primary key.
- New! Experimental (alpha stage) support for Android servers!
- New! Added support for `X-HTTP-Method-Override` to work behind corporate firewalls.
- New Sample! Server in DLL
- Added new method in the dataset helper to load data into a dataset from a specific JSONArray property of a JSONObject `procedure TDataSetHelper.LoadJSONArrayFromJSONObjectProperty(const AJSONObjectString: string; const aPropertyName: String);`
- Improved! New constants defined in `HTTP_STATUS` to better describe the http status response.
- Improved! Now Firebird RQL' SQLGenerator can include primary key in `CreateInsert` if not autogenerated.
- New! Added support for `TArray<String>`, `TArray<Integer>` and `TArray<Double>` in default JSON serializer (Thank you [Pedro Oliveira](https://github.com/pedrooliveira01))
- Improved JWT Standard Compliance! Thanks to [Vinicius Sanchez](https://github.com/viniciussanchez) for his work on [issue #241](https://github.com/danieleteti/delphimvcframework/issues/241)
- Improved! DMVCFramework now has 130+ unit tests that checks its functionalities at each build!
- Improved! Better exception handling in `OnBeforeDispatch` (Thanks to [Spinettaro](https://github.com/spinettaro))
- New! `StrToJSONObject` function to safely parse a string into a JSON object.
- New! Serialization callback for custom `TDataSet` descendants serialization in `TMVCJsonDataObjectsSerializer`.
```delphi
procedure TMainForm.btnDataSetToJSONArrayClick(Sender: TObject);
@ -572,10 +556,6 @@ end;
- **Breaking Change!** In `MVCActiveRecord` attribute `MVCPrimaryKey` has been removed and merged with `MVCTableField`, so now `TMVCActiveRecordFieldOption` is a set of `foPrimaryKey`, `foAutoGenerated`, `foTransient` (check `activerecord_showcase.dproj` sample).
- **Breaking Change!** Middleware `OnAfterControllerAction` are now invoked in the same order of `OnBeforeControllerAction` (previously were invoked in reversed order).
- **Deprecated!** `TDataSetHolder` is deprecated! Use the shining new `ObjectDict(boolean)` instead.
- Added ability to serialize/deserialize types enumerated by an array of mapped values (Thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
@ -622,6 +602,40 @@ end;
|Delphi 10.1 Berlin| `packages\d101\dmvcframework_group.groupproj`|
|Delphi 10.0 Seattle| `packages\d100\dmvcframework_group.groupproj`|
### Breaking Changes in 3.2.0-boron
- In `MVCActiveRecord` attribute `MVCPrimaryKey` has been removed and merged with `MVCTableField`, so now `TMVCActiveRecordFieldOption` is a set of `foPrimaryKey`, `foAutoGenerated`, `foTransient` (check `activerecord_showcase.dproj` sample).
- Middleware `OnAfterControllerAction` are now invoked in the same order of `OnBeforeControllerAction` (previously were invoked in reversed order).
- `TMVCEngine` is no more responsible for static file serving. If you need static files used the new `TMVCStaticFilesMiddleware` (check the sample). As consequence `TMVCConfigKey.DocumentRoot`, `TMVCConfigKey.IndexDocument` and `TMVCConfigKey.FallbackResource` are no more available.
- `TMVCEngine.Config` property is now read-only. Can be changed only in the anonymous method injected in the constructor.
```delphi
// This is valid
////////////////////////////////////////
FMVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
// session timeout (0 means session cookie)
Config[TMVCConfigKey.SessionTimeout] := '0';
//Other Configurations
end);
FMVC.AddController(TMyController);
// This is not valid (exception is raised)
/////////////////////////////////////////
FMVC := TMVCEngine.Create(Self);,
FMVC.Config[TMVCConfigKey.SessionTimeout] := '0'; {run-time error here}
FMVC.AddController(TMyController);
```
### Bug Fixes in 3.2.0-boron
- Fixed! [issue38](https://github.com/danieleteti/delphimvcframework/issues/38)

View File

@ -17,7 +17,7 @@ type
[MVCPath('/search/($searchtext)/($page)')]
[MVCProduces('text/plain', 'UTF-8')]
[MVCConsumes('text/html')]
procedure SearchCustomers(CTX: TWebContext);
procedure SearchCustomers;
[MVCHTTPMethod([httpGet])]
[MVCPath('/people/($id)')]
@ -54,17 +54,17 @@ begin
Render('This is the root path');
end;
procedure TRoutingSampleController.SearchCustomers(CTX: TWebContext);
procedure TRoutingSampleController.SearchCustomers;
var
search: string;
P: Integer;
orderby: string;
begin
search := CTX.Request.Params['searchtext'];
P := CTX.Request.ParamsAsInteger['page'];
search := Context.Request.Params['searchtext'];
P := Context.Request.ParamsAsInteger['page'];
orderby := '';
if CTX.Request.QueryStringParamExists('order') then
orderby := CTX.Request.QueryStringParam('order');
if Context.Request.QueryStringParamExists('order') then
orderby := Context.Request.QueryStringParam('order');
Render(Format(
'SEARCHTEXT: "%s"' + sLineBreak +
'PAGE: %d' + sLineBreak +

View File

@ -22,14 +22,17 @@ implementation
{$R *.dfm}
uses RoutingSampleControllerU;
uses RoutingSampleControllerU, MVCFramework.Commons;
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
DMVC := TMVCEngine.Create(self);
DMVC := TMVCEngine.Create(self,
procedure(Config: TMVCConfig)
begin
if IsConsole then
DMVC.Config['ISAPI_PATH'] := '/sampleisapi/isapiapp.dll';
end);
DMVC.AddController(TRoutingSampleController);
if IsConsole then
DMVC.Config['ISAPI_PATH'] := '/sampleisapi/isapiapp.dll';
end;
end.

View File

@ -37,16 +37,19 @@ uses
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(Self);
MVC.Config[TMVCConfigKey.SessionTimeout] := '30';
MVC.Config[TMVCConfigKey.DefaultContentType] := 'text/html';
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.SessionTimeout] := '30';
Config[TMVCConfigKey.DefaultContentType] := 'text/html';
end);
MVC
.AddController(TApp1MainController)
.AddController(TAdminController)
.AddMiddleware(TMVCBasicAuthenticationMiddleware.Create(TAuthenticationSample.Create))
.AddMiddleware(TMVCStaticFilesMiddleware.Create(
'/', { StaticFilesPath }
'..\..\www' { DocumentRoot }
'/', { StaticFilesPath }
'..\..\www' { DocumentRoot }
));
end;

View File

@ -34,8 +34,11 @@ uses
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(Self);
MVC.Config[TMVCConfigKey.ViewPath] := '.\www\public_html';
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.ViewPath] := '.\www\public_html';
end);
// Web files
MVC.AddMiddleware(TMVCStaticFilesMiddleware.Create('/', '.\www\public_html'));

View File

@ -36,18 +36,21 @@ uses
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(self);
MVC := TMVCEngine.Create(self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.ViewPath] :=
ExtractFilePath(GetModuleName(HInstance)) + '..\..\templates';
Config[TMVCConfigKey.DefaultContentType] := TMVCMediaType.TEXT_HTML;
end);
MVC.AddController(TFileUploadController);
MVC.AddMiddleware(TMVCTraceMiddleware.Create);
MVC.AddMiddleware(TMVCStaticFilesMiddleware.Create(
'/', { StaticFilesPath }
ExtractFilePath(GetModuleName(HInstance)) + '..\..\document_root', { DocumentRoot }
'index.html' {IndexDocument - Before it was named fallbackresource}
'index.html' { IndexDocument - Before it was named fallbackresource }
));
MVC.SetViewEngine(TMVCTemplateProViewEngine);
MVC.Config[TMVCConfigKey.ViewPath] := ExtractFilePath(GetModuleName(HInstance)
) + '..\..\templates';
MVC.Config[TMVCConfigKey.DefaultContentType] := TMVCMediaType.TEXT_HTML;
end;

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -50,17 +50,21 @@ begin
JWT.CustomClaims['mycustomvalue'] := 'hello there';
end;
MVC := TMVCEngine.Create(Self);
MVC.Config[TMVCConfigKey.SessionTimeout] := '30';
MVC.Config[TMVCConfigKey.DefaultContentType] := 'text/html';
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.SessionTimeout] := '30';
Config[TMVCConfigKey.DefaultContentType] := 'text/html';
end);
MVC
.AddController(TApp1MainController)
.AddController(TAdminController)
.AddMiddleware(TMVCJWTAuthenticationMiddleware.Create(TAuthenticationSample.Create, 'mys3cr37', '/login', LClaimsSetup,
[TJWTCheckableClaim.ExpirationTime, TJWTCheckableClaim.NotBefore, TJWTCheckableClaim.IssuedAt], 300))
.AddMiddleware(TMVCJWTAuthenticationMiddleware.Create(TAuthenticationSample.Create, 'mys3cr37', '/login',
lClaimsSetup,
[TJWTCheckableClaim.ExpirationTime, TJWTCheckableClaim.NotBefore, TJWTCheckableClaim.IssuedAt], 300))
.AddMiddleware(TMVCStaticFilesMiddleware.Create(
'/', { StaticFilesPath }
'..\..\www' { DocumentRoot }
'/', { StaticFilesPath }
'..\..\www' { DocumentRoot }
));
end;

View File

@ -27,6 +27,7 @@ implementation
{$R *.dfm}
uses
AppControllerU,
System.Generics.Collections,
@ -53,9 +54,12 @@ begin
JWT.LiveValidityWindowInSeconds := 10; // 60 * 60; // 1 hour
end;
MVC := TMVCEngine.Create(Self);
MVC.Config[TMVCConfigKey.SessionTimeout] := '30';
MVC.Config[TMVCConfigKey.DefaultContentType] := 'text/html';
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.SessionTimeout] := '30';
Config[TMVCConfigKey.DefaultContentType] := 'text/html';
end);
MVC.AddController(TApp1MainController).AddController(TAdminController)
.AddMiddleware(TMVCJWTAuthenticationMiddleware.Create(TAuthenticationSample.Create, lClaimsSetup, 'mys3cr37',
'/login', [TJWTCheckableClaim.ExpirationTime, TJWTCheckableClaim.NotBefore, TJWTCheckableClaim.IssuedAt], 0

View File

@ -31,10 +31,12 @@ uses AppControllerU, MiddlewareSample1;
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(Self);
MVC.Config[TMVCConfigKey.SessionTimeout] := '30';
MVC.Config[TMVCConfigKey.DefaultContentType] := 'text/plain';
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.SessionTimeout] := '30';
Config[TMVCConfigKey.DefaultContentType] := 'text/plain';
end);
MVC
.AddController(TApp1MainController)
.AddMiddleware(TMVCSalutationMiddleware.Create)

View File

@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{BE3A3D14-17E0-45C1-BD21-4710DE4CBCC2}</ProjectGuid>
<ProjectVersion>18.6</ProjectVersion>
<ProjectVersion>18.8</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>OutputCacheWithRedis.dpr</MainSource>
<Base>True</Base>
@ -18,18 +18,8 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''">
<Base_iOSDevice32>true</Base_iOSDevice32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
<Base_iOSDevice64>true</Base_iOSDevice64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''">
<Base_iOSSimulator>true</Base_iOSSimulator>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
@ -38,6 +28,11 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -117,66 +112,50 @@
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
<VerInfo_Keys>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=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<Android_NotificationIcon24>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png</Android_NotificationIcon24>
<Android_NotificationIcon36>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png</Android_NotificationIcon36>
<Android_NotificationIcon48>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png</Android_NotificationIcon48>
<Android_NotificationIcon72>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png</Android_NotificationIcon72>
<Android_NotificationIcon96>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png</Android_NotificationIcon96>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice32)'!=''">
<iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40>
<iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152>
<iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024>
<iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60>
<iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768>
<iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80>
<VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
<iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<VerInfo_Keys>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=</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76>
<iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536>
<iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048>
<iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80>
<iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
<iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40>
<iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152>
<iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024>
<iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60>
<iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768>
<iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80>
<VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
<iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76>
<iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536>
<iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048>
<iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80>
<iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSSimulator)'!=''">
<iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40>
<iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60>
<iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024>
<iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152>
<iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80>
<iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768>
<iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120>
<iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048>
<iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536>
<iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76>
<iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
<AUP_WRITE_CALENDAR>true</AUP_WRITE_CALENDAR>
<AUP_ACCESS_COARSE_LOCATION>true</AUP_ACCESS_COARSE_LOCATION>
<AUP_READ_CALENDAR>true</AUP_READ_CALENDAR>
<AUP_WRITE_EXTERNAL_STORAGE>true</AUP_WRITE_EXTERNAL_STORAGE>
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
<AUP_CAMERA>true</AUP_CAMERA>
<Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
<Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
<EnabledSysJars>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</EnabledSysJars>
<AUP_CALL_PHONE>true</AUP_CALL_PHONE>
<AUP_ACCESS_FINE_LOCATION>true</AUP_ACCESS_FINE_LOCATION>
<AUP_READ_EXTERNAL_STORAGE>true</AUP_READ_EXTERNAL_STORAGE>
<AUP_INTERNET>true</AUP_INTERNET>
<Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
<Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
<Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
<Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
<Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
<AUP_READ_PHONE_STATE>true</AUP_READ_PHONE_STATE>
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX32)'!=''">
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<Base_OSX32>true</Base_OSX32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<Manifest_File>(None)</Manifest_File>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
@ -341,12 +320,20 @@
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\xml</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
@ -359,12 +346,26 @@
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeX86File"/>
<DeployClass Name="AndroidServiceOutput">
@ -372,84 +373,216 @@
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV21">
<Platform Name="Android">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon24">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_NotificationIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Strings">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
@ -519,6 +652,9 @@
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="Android64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
@ -549,6 +685,17 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024x768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -560,6 +707,39 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1668x2388">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -571,6 +751,61 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048x2732">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2224">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2388x1668">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2732x2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -582,6 +817,116 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768x1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1125">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1136x640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1242x2688">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1334">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch1792">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2208">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2436">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2688x1242">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
@ -615,10 +960,35 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch750">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch828">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
@ -662,6 +1032,10 @@
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
@ -684,6 +1058,12 @@
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOutput_Android32">
<Platform Name="Android64">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
@ -721,13 +1101,13 @@
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="iOSDevice32">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimulator">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="OSX32">False</Platform>
<Platform value="OSX64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>

View File

@ -27,7 +27,7 @@ implementation
{$R *.dfm}
uses PeopleControllerU;
uses PeopleControllerU, MVCFramework.Commons;
procedure TwmMain.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
@ -37,10 +37,12 @@ end;
procedure TwmMain.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(Self);
// required by the TMVCCacheController
MVC.Config['redis_connection_string'] := '127.0.0.1:6379';
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
// required by the TMVCCacheController
MVC.Config['redis_connection_string'] := '127.0.0.1:6379';
end);
MVC.AddController(TPeopleController);
end;

View File

@ -2,7 +2,7 @@
//
// Delphi MVC Framework
//
// Copyright (c) 2010-2019 Daniele Teti and the DMVCFramework Team
// Copyright (c) 2010-2020 Daniele Teti and the DMVCFramework Team
//
// https://github.com/danieleteti/delphimvcframework
//

View File

@ -360,6 +360,12 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\default.txvpck" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\RenderSampleControllerU\default.txaPackage" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
@ -372,12 +378,24 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Linux64">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\renders\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="bin\renders.exe" Configuration="Release" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>renders.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\renders1\default.txvpck" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
@ -389,24 +407,6 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="bin\renders.exe" Configuration="Release" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>renders.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Linux64">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\default.txvpck" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_renders\renders1\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>

View File

@ -26,19 +26,24 @@ implementation
{$R *.dfm}
uses
App1MainControllerU,
MVCFramework.Middleware.StaticFiles;
MVCFramework.Middleware.StaticFiles, MVCFramework.Commons;
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
FMVCEngine := TMVCEngine.Create(Self);
FMVCEngine.Config['view_path'] := '..\Debug\HTML5Application';
FMVCEngine.AddController(TApp1MainController);
FMVCEngine := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config['view_path'] := '..\Debug\HTML5Application';
end);
FMVCEngine.AddController(
TApp1MainController);
FMVCEngine.AddMiddleware(TMVCStaticFilesMiddleware.Create(
'/', { StaticFilesPath }
'HTML5Application\public_html', { DocumentRoot }
'index.html' {IndexDocument - Before it was named fallbackresource}
'index.html' { IndexDocument - Before it was named fallbackresource }
));
end;

View File

@ -11,10 +11,8 @@ uses System.SysUtils,
type
TWebModule1 = class(TWebModule)
procedure WebModuleCreate(Sender: TObject);
private
MVC: TMVCEngine;
public
{ Public declarations }
end;
@ -31,13 +29,14 @@ uses AppControllerU;
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(Self);
MVC.Config[TMVCConfigKey.SessionTimeout] := '10'; // 10minutes
MVC.Config[TMVCConfigKey.DefaultContentType] := 'text/plain';
// comment the line to use default session type (memory)
MVC.Config[TMVCConfigKey.SessionType] := 'memoryController';
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.SessionTimeout] := '10'; // 10minutes
Config[TMVCConfigKey.DefaultContentType] := 'text/plain';
// comment the line to use default session type (memory)
MVC.Config[TMVCConfigKey.SessionType] := 'memoryController';
end);
MVC.AddController(TApp1MainController);
end;

View File

@ -2,7 +2,7 @@
<body>
<h2>SOAP and REST</h2>
<p>This example uses the allow_unhandled_action option to allow standard Delphi SOAP webservice functionality.</p>
<p>Visit <a href="/soap">/soap</a> for WSDL</p>
<p>Visit <a href="/wsdl">/wsdl</a> for WSDL</p>
<p>Visit <a href="/customers">/customer</a> for Customer REST</p>
</body>
</html>

View File

@ -29,6 +29,7 @@ object wmSOAPREST: TwmSOAPREST
object WSDLHTMLPublish: TWSDLHTMLPublish
WebDispatch.MethodType = mtAny
WebDispatch.PathInfo = 'wsdl*'
TargetNamespace = 'http://tempuri.org/'
PublishOptions = [poUTF8ContentType]
Left = 60
Top = 123

View File

@ -31,19 +31,24 @@ implementation
{$R *.dfm}
uses
MVCFramework.Middleware.StaticFiles,
RESTControllerCustomerU;
procedure TwmSOAPREST.WebModuleCreate(Sender: TObject);
begin
FMVCEngine := TMVCEngine.Create(self);
FMVCEngine.Config[TMVCConfigKey.AllowUnhandledAction] := 'true';
FMVCEngine := TMVCEngine.Create(self,
procedure(Config: TMVCConfig)
begin
Config[TMVCConfigKey.AllowUnhandledAction] := 'true';
end);
FMVCEngine.AddController(TControllerCustomer);
FMVCEngine.AddMiddleware(TMVCStaticFilesMiddleware.Create(
'/', { StaticFilesPath }
'www', { DocumentRoot }
'index.html' {IndexDocument - Before it was named fallbackresource}
'index.html' { IndexDocument - Before it was named fallbackresource },
False
));
end;
@ -54,7 +59,7 @@ begin
end;
procedure TwmSOAPREST.wmSOAPRESTSoapActionAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
WSDLHTMLPublish.ServiceInfo(Sender, Request, Response, Handled);
end;

View File

@ -24,19 +24,23 @@ implementation
{$R *.dfm}
uses MyControllerU;
uses MyControllerU, MVCFramework.Commons;
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.Content := '<html><heading/><body>Web Server Application</body></html>';
Response.Content := '<html><heading/><body>DMVCFramework Server Application</body></html>';
end;
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
MVC := TMVCEngine.Create(Self);
MVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
Config['ISAPI_PATH'] := '/isapi32/myisapi.dll';
end);
MVC.AddController(TMyController);
MVC.Config['ISAPI_PATH'] := '/isapi32/myisapi.dll';
end;
procedure TWebModule1.WebModuleDestroy(Sender: TObject);

View File

@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIF9DCCA9ygAwIBAgIJAOFuHMKs/11KMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD
VQQGEwJJVDEOMAwGA1UECAwFSVRBTFkxDTALBgNVBAcMBFJPTUUxHzAdBgNVBAoM
FkJJVCBUSU1FIFBST0ZFU1NJT05BTFMxGjAYBgNVBAMMEXd3dy5taW9zZXJ2ZXIu
Y29tMSMwIQYJKoZIhvcNAQkBFhR3ZWJtYXN0ZXJAYml0dGltZS5pdDAeFw0xODA1
MTYwNzM3NTJaFw0yMTA1MTUwNzM3NTJaMIGOMQswCQYDVQQGEwJJVDEOMAwGA1UE
CAwFSVRBTFkxDTALBgNVBAcMBFJPTUUxHzAdBgNVBAoMFkJJVCBUSU1FIFBST0ZF
U1NJT05BTFMxGjAYBgNVBAMMEXd3dy5taW9zZXJ2ZXIuY29tMSMwIQYJKoZIhvcN
AQkBFhR3ZWJtYXN0ZXJAYml0dGltZS5pdDCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAJxYF2WbI+vBbhb7qy5hA2CtYVdManSUTtr8f2CSRCMjfxAuaTdQ
Ga5y3pMW4iLNGJjnLpJOZvrHGsJbkkL/uUJh/Q9QQpaq0G+XHuZ9GVxq28/ZJDKV
wMemAh4JVNrPSCNOj/6ZD/3phM84a4L6wlLBMbPofeo9tEP/BV6PByPQfGDja8JY
mpC1r/TiUTdmk+ylM8Cjv8NLrrWjZnLxTNUTNtiXM0orBoKnwjazFujJNZI5hVdF
LMjNKFI3gS08o2jqlrmaNqNQFfll7ax/S1t4R8vIme7DfeOAll4iOq/QzYQ3Ilfj
9Z+j0viSomcia7s/7A2u+Ad4b5dhrjZOADxxps1qCynVGkU5cNyj7ra4V6CQSgwB
41EIJMgM5pEhrKf4yta3Xaob44/Ce7ThZil92P9o7h8AcYtrCZEcaaT3dbsUBz5e
UlMwJ9uSkk/cZ+v9uPg5TgFb0ib+fxbucVAet5jRmQthuJXLi+jRY8CKjH0PUj5u
soc/EY5xlIx/wKVJc7rgRzvqfZgrU3d5+XBL/f7SK6R6hKQ8wIYwpcIijzOnjiMz
YnsmEBf+V7l7xuVK8KYAbLkhw4tWUNVBJGrLhem23JKogfb+Ap7zvuUD+uJQDvkN
/i4cxKOOPFPihKNpJgtbmHlyJNBSzQ5mAAAQXJIDrNDB5FEI0veu1n7NAgMBAAGj
UzBRMB0GA1UdDgQWBBT70tiJ+vU0yMF/Q0e0QlIhO9RcmDAfBgNVHSMEGDAWgBT7
0tiJ+vU0yMF/Q0e0QlIhO9RcmDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
CwUAA4ICAQAee/uDpIiiMm4N3gMCHODx6dYuGda3nbGIe5R/MeJJk01gIA/eFzRi
lXfBXQqSi4HckXK53kDLkQl6iZQTskhsCMqkazkCWZfzj9nNGSWXoOMDVARnH/eQ
BnmS8coiFBI3m3Dm7njAL7/yIFHd84RR3eu/diWM+oFMAQhP6mjo+egGDzxliav2
IPbs0INYGwxVsX9eizw9bc6VNin4HH25uEd6YKw/NEC1Hh3PCdNIkzhi12lWtL7Y
L8bwwaNvq//nkpHmU1URYIC74ooRQ0pmzNu5Q+UgXJgNTOYKk8rViTGQEvvKbwc+
2OMrHXwtpF5KHyktDGrpNQR9OQjcxcf2oVxSpp74oJkZhLpc0IydEEFXhlfNJTFp
H6imbyTPwgco8bnv1x6jhVr7tcumRBrdA0Xukathg4UkzAThZwkqBvDtJOpT9Whj
YgqVjpe1siWZkmUizSB/SSLFl9OlVD54pPY6hCNRU+iY113GzTP+aliExDfsGf4y
H1xyvXzM/tJ8s76IQfyihBpLn436J5Y59lHzUEhV30FGXzx4uwo2pk5YXDmSux1I
A5uMV80VjdWb/99orGK3XyN33twR9VSv253tsQtf9SeSID/U2+AYCEzPqNskZI/5
x9rPErp4IlrYsxpxODAssVJ5pJxPE3TrtBXy22a2iof5LvW7muTlrQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -32,6 +32,7 @@ uses
{$R *.dfm}
procedure Twm.WebModuleCreate(Sender: TObject);
begin
MVCEngine := TMVCEngine.Create(self);
@ -39,7 +40,7 @@ begin
MVCEngine.AddMiddleware(TMVCStaticFilesMiddleware.Create(
'/', { StaticFilesPath }
TPath.Combine(AppPath, '..\..\www'), { DocumentRoot }
'index.html' {IndexDocument - Before it was named fallbackresource}
'index.html' { IndexDocument - Before it was named fallbackresource }
));
end;

View File

@ -445,22 +445,22 @@ type
function LinksData: TMVCStringDictionaryList;
end;
// IMVCStringDictionary = interface
// ['{164117AD-8DDD-47F7-877C-453979707D10}']
// function GetItems(const Key: string): string;
// procedure SetItems(const Key, Value: string);
// procedure Clear;
//// function Add(const Name, Value: string): IMVCStringDictionary;
// function TryGetValue(const Name: string; out Value: string): Boolean; overload;
// function TryGetValue(const Name: string; out Value: Integer): Boolean; overload;
// function Count: Integer;
// function GetEnumerator: TDictionary<string, string>.TPairEnumerator;
// function ContainsKey(const Key: string): Boolean;
// function Keys: TArray<string>;
// property Items[const Key: string]: string read GetItems; default;
// end;
// IMVCStringDictionary = interface
// ['{164117AD-8DDD-47F7-877C-453979707D10}']
// function GetItems(const Key: string): string;
// procedure SetItems(const Key, Value: string);
// procedure Clear;
/// / function Add(const Name, Value: string): IMVCStringDictionary;
// function TryGetValue(const Name: string; out Value: string): Boolean; overload;
// function TryGetValue(const Name: string; out Value: Integer): Boolean; overload;
// function Count: Integer;
// function GetEnumerator: TDictionary<string, string>.TPairEnumerator;
// function ContainsKey(const Key: string): Boolean;
// function Keys: TArray<string>;
// property Items[const Key: string]: string read GetItems; default;
// end;
TMVCStringDictionary = class //(TInterfacedObject, IMVCStringDictionary)
TMVCStringDictionary = class // (TInterfacedObject, IMVCStringDictionary)
strict private
function GetItems(const Key: string): string;
procedure SetItems(const Key, Value: string);
@ -540,16 +540,17 @@ type
TMVCConfig = class sealed
private
FConfig: TMVCStringDictionary;
FFreezed: Boolean;
function GetValue(const AIndex: string): string;
function GetValueAsInt64(const AIndex: string): Int64;
procedure SetValue(const AIndex: string; const aValue: string);
procedure CheckNotFreezed; inline;
protected
{ protected declarations }
public
constructor Create;
destructor Destroy; override;
procedure Freeze;
function Keys: TArray<string>;
function ToString: string; override;
procedure SaveToFile(const AFileName: string);
@ -861,10 +862,19 @@ end;
{ TMVCConfig }
procedure TMVCConfig.CheckNotFreezed;
begin
if FFreezed then
begin
raise EMVCException.Create('Configuration in freezed - no more changes allowed') at ReturnAddress;
end;
end;
constructor TMVCConfig.Create;
begin
inherited Create;
FConfig := TMVCStringDictionary.Create;
FFreezed := False;
end;
destructor TMVCConfig.Destroy;
@ -873,6 +883,11 @@ begin
inherited Destroy;
end;
procedure TMVCConfig.Freeze;
begin
FFreezed := True;
end;
function TMVCConfig.GetValue(const AIndex: string): string;
begin
if FConfig.ContainsKey(AIndex) then
@ -922,6 +937,7 @@ end;
procedure TMVCConfig.SetValue(const AIndex, aValue: string);
begin
CheckNotFreezed;
FConfig.Add(AIndex, aValue);
end;

View File

@ -2012,6 +2012,7 @@ begin
AConfigAction(FConfig);
LogExitMethod('Custom configuration method');
end;
FConfig.Freeze;
SaveCacheConfigValues;
RegisterDefaultsSerializers;
LoadSystemControllers;

Binary file not shown.