├── FMLab
├── $tf
│ ├── 0
│ │ ├── b37048b0-ce4e-4e7e-9902-ecedff8777d9.gz
│ │ └── fe7cf740-4011-43e2-ab3b-e0eb36b1ae39.gz
│ ├── 1
│ │ ├── 383bb791-f417-4dd9-9d9f-83221d18622a.gz
│ │ ├── 77ea3d91-eeed-44c8-83ed-5094142ca005.gz
│ │ ├── 991e67b1-81cc-433e-9b30-595eb688292e.gz
│ │ ├── a337a441-a48d-450a-a546-d5bb8c48e136.gz
│ │ └── f5a22731-c770-4623-9e5d-83a7f66340f9.gz
│ ├── 2
│ │ ├── 06110bd2-084d-4c8b-964d-aac630227768.gz
│ │ ├── 4b3dc482-1ed7-421a-ba8d-d0a76d2fbad5.gz
│ │ ├── 5108e4d2-8aca-41f8-b85d-aebdf3f90f98.gz
│ │ ├── 514f6032-005e-49d9-8867-c28c093103ec.gz
│ │ ├── 54e0e862-b17f-45ef-8540-d29b95c7984b.gz
│ │ ├── ae6f73b2-b985-4edf-aa93-76eef3127ebd.gz
│ │ └── e0a94a22-e548-440a-ba72-5ffb7dfb2005.gz
│ ├── 3
│ │ ├── dec4f863-7c2a-44e1-844d-407675224f03.gz
│ │ └── f4875a63-c933-4612-b8b5-046164d181a7.gz
│ ├── 4
│ │ ├── 418e4ee4-9ef6-47c6-8d1a-675cfd9b077e.gz
│ │ ├── 6e13a834-578e-4360-a6d6-42ce671ce661.gz
│ │ └── baea85a4-6569-4641-8161-00d21d5fcc1d.gz
│ ├── 5
│ │ ├── 99ffa485-a5e8-4d73-a22e-defc18d14662.gz
│ │ └── dca24a05-c05d-46ba-bc00-87e1bfd6135c.gz
│ ├── 6
│ │ ├── 17432966-7fb7-4c4b-a1c0-4de1b774b98e.gz
│ │ ├── 777f1156-94cb-40b1-a9e8-87f2f10042d1.gz
│ │ ├── dd7ddea6-4367-4298-a4fd-f347aeb7dd5f.gz
│ │ └── fca62e46-c2a4-4434-a5bc-566b8c4aae95.gz
│ ├── 7
│ │ ├── 1b53f527-af30-42c1-953b-bfb50c2b6b83.gz
│ │ └── ae332fc7-c75c-41b4-9d46-926279288b2b.gz
│ ├── 8
│ │ ├── 09bb0848-94bd-4942-a276-f55ac614053e.gz
│ │ ├── 220bdbb8-4f22-425b-a94e-5749d2603d03.gz
│ │ ├── 813b2f98-3983-48ea-ab18-40cde25b7614.gz
│ │ ├── ca3997d8-e6d1-4689-82ce-0aeaa58b077f.gz
│ │ └── cd6dd508-4613-4cd4-9949-48f97414f590.gz
│ ├── 9
│ │ ├── 0279f1a9-f7b3-4b22-8085-bd9b8244f52e.gz
│ │ ├── 25ddbd39-e3fa-4fe6-beb7-e7c9b2034b43.gz
│ │ ├── 39be00b9-89b0-4fcd-b2a2-8107af1e968c.gz
│ │ ├── 8b281bd9-cec6-42d1-a75c-f29bb9becda2.gz
│ │ └── bdb72cd9-30b6-4eb9-9d4a-d8c4f816f79e.gz
│ ├── 10
│ │ ├── 05ea4a4a-1c13-4525-aab4-3658155529d2.gz
│ │ ├── 4275258a-e231-4b67-a08c-f16733c3c8fe.gz
│ │ ├── 6920d30a-7a73-45a8-bf2e-90aabe0aad10.gz
│ │ ├── c890a4fa-b780-4bc4-8546-08eb226f28d4.gz
│ │ ├── e239beca-1906-4031-86e2-9709ad38c44e.gz
│ │ └── f045ba2a-a7b3-453c-a9cf-ebc68b80d3c6.gz
│ ├── 12
│ │ ├── 338bcb7c-64b4-4274-879e-9a0716b597d5.gz
│ │ ├── cffcb19c-9be5-4281-bbc3-77da08d926dc.gz
│ │ ├── d183ad7c-b15a-4c01-b586-9304f788c006.rw
│ │ └── fe6345fc-522e-42c6-bfff-ef57c74676a6.gz
│ ├── 13
│ │ ├── 6df4da5d-44d1-49e7-9406-98caa32b7f48.gz
│ │ ├── 7fa2e96d-8f32-458f-b2f7-7243631c9140.gz
│ │ ├── 7fa577fd-4f37-4da5-86a3-88c47cd54d66.gz
│ │ ├── 88b41f3d-38fb-4aa4-a0a0-7640b8038c57.gz
│ │ └── cab05a9d-8fa0-41da-a68d-86b5bba87a1f.gz
│ ├── 14
│ │ ├── 230b847e-80cf-4895-979d-a63fda389f69.gz
│ │ ├── 2f08363e-e558-4043-8cd7-f9668d570513.gz
│ │ ├── 991e6c0e-64e3-4957-9863-77840f7ef29c.gz
│ │ └── c1c2c75e-35c1-4672-9598-908b89dc96d4.gz
│ ├── 15
│ │ ├── 4769b42f-2897-4084-8645-58a2ca2c1cf8.gz
│ │ ├── 576cdcbf-9d40-4fb8-803b-abe8f5deb00f.gz
│ │ ├── bb4aac3f-7dd9-4084-a47f-04f530a89e69.gz
│ │ ├── bf0cc88f-766e-4ee4-953f-42e752258501.gz
│ │ ├── caeb9e5f-4233-46ab-99c1-094cdfbb3e46.gz
│ │ ├── ccbcdb2f-8710-4dd0-90e5-19fe171147d2.gz
│ │ ├── f57743cf-99c9-4ef6-8d8c-b9c53e9e1c4f.gz
│ │ └── fc3ce97f-a9ca-4939-879e-7b047c44f23a.gz
│ ├── localversion.tf1
│ ├── localversion.tfb
│ ├── pendingchanges.tf1
│ ├── pendingchanges.tfb
│ └── properties.tf1
├── AxForm_FmtChargeType.xml
├── AxForm_FmtCustomer.xml
├── AxForm_FmtCustomerWorkflow.CTP3.xml
├── AxMenuItemDisplay_FMTCustomerWorkflow.CTP3.xml
├── AxQuery_FMTCustomerWorkflowQuery.CTP3.xml
├── AxWorkflowCategory_FMTWorkflowCategory.CTP3.xml
├── ConnectorClientApplication
│ ├── ActivityMessage.cs
│ ├── App.config
│ ├── ConnectorServiceApplication.csproj
│ ├── FleetCustomerPlainText.xslt
│ ├── Helper.cs
│ ├── Program.cs
│ ├── mainForm.Designer.cs
│ ├── mainForm.cs
│ ├── mainForm.resx
│ └── uploadFMCustomer.xml
├── CreateAADApplication
│ └── Microsoft.IdentityModel.Clients.ActiveDirectory.xml
├── DemoBP.zip
├── DriversLicenseChecker.cs
├── DynamicsAX.ExcelManifest.xml
├── EDT
│ ├── AxEdt_FMTCCExpiryDate.xml
│ ├── AxEdt_FMTChargeTypeId.xml
│ ├── AxEdt_FMTCreditCardNum.xml
│ ├── AxEdt_FMTCustomerRecId.xml
│ ├── AxEdt_FMTDescription.xml
│ ├── AxEdt_FMTDriversLicense.xml
│ └── AxEdt_FMTName.xml
├── FMTutorialDataModel.axpp
├── Lab10-1
│ └── Adding BI to workspaces.axpp
├── Lab10-2
│ ├── Add contextual BI to a form - After Lab.axpp
│ ├── Add contextual BI to a form - Before Lab.axpp
│ ├── Add contextual BI to a form.axpp
│ ├── FMBILabHelper.xml
│ ├── FMBIRevenueByVehicleModel.xml
│ └── TmpDBBIFMRevenueByVehicleModelByMonth.xml
├── Lab10-3
│ └── FMRentalDetailsReport.axpp
├── ODataConsoleApplication
│ ├── App.config
│ ├── AuthenticationHelper.cs
│ ├── BrowserForm.cs
│ ├── BrowserForm.designer.cs
│ ├── BrowserForm.resx
│ ├── CloudEnvironment.Config
│ ├── ODataConsoleApplication.csproj
│ ├── ODataConsoleApplication.sln
│ ├── ODataProxies.odata.config
│ ├── ODataProxies.tt
│ ├── Program.cs
│ └── packages.config
├── Odata4ConsoleApplication
│ ├── App.config
│ ├── AuthenticationHelper.cs
│ ├── BrowserForm.cs
│ ├── BrowserForm.designer.cs
│ ├── BrowserForm.resx
│ ├── ODataProxyGenerator.tt
│ ├── ODataProxyGenerator.ttinclude
│ ├── Odata4ConsoleApplication.csproj
│ └── Program.cs
├── TaskRecorderScreenshot
│ ├── background.js
│ ├── manifest.json
│ └── screenshot.js
├── TestFiles
│ ├── AxClass_FMUnitTestSample.xml
│ ├── CodeCoverage.config
│ └── Default.RunSettings
└── json-ie.reg
├── README.md
└── SECURITY.md
/FMLab/$tf/0/b37048b0-ce4e-4e7e-9902-ecedff8777d9.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/0/b37048b0-ce4e-4e7e-9902-ecedff8777d9.gz
--------------------------------------------------------------------------------
/FMLab/$tf/0/fe7cf740-4011-43e2-ab3b-e0eb36b1ae39.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/0/fe7cf740-4011-43e2-ab3b-e0eb36b1ae39.gz
--------------------------------------------------------------------------------
/FMLab/$tf/1/383bb791-f417-4dd9-9d9f-83221d18622a.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/1/383bb791-f417-4dd9-9d9f-83221d18622a.gz
--------------------------------------------------------------------------------
/FMLab/$tf/1/77ea3d91-eeed-44c8-83ed-5094142ca005.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/1/77ea3d91-eeed-44c8-83ed-5094142ca005.gz
--------------------------------------------------------------------------------
/FMLab/$tf/1/991e67b1-81cc-433e-9b30-595eb688292e.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/1/991e67b1-81cc-433e-9b30-595eb688292e.gz
--------------------------------------------------------------------------------
/FMLab/$tf/1/a337a441-a48d-450a-a546-d5bb8c48e136.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/1/a337a441-a48d-450a-a546-d5bb8c48e136.gz
--------------------------------------------------------------------------------
/FMLab/$tf/1/f5a22731-c770-4623-9e5d-83a7f66340f9.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/1/f5a22731-c770-4623-9e5d-83a7f66340f9.gz
--------------------------------------------------------------------------------
/FMLab/$tf/10/05ea4a4a-1c13-4525-aab4-3658155529d2.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/10/05ea4a4a-1c13-4525-aab4-3658155529d2.gz
--------------------------------------------------------------------------------
/FMLab/$tf/10/4275258a-e231-4b67-a08c-f16733c3c8fe.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/10/4275258a-e231-4b67-a08c-f16733c3c8fe.gz
--------------------------------------------------------------------------------
/FMLab/$tf/10/6920d30a-7a73-45a8-bf2e-90aabe0aad10.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/10/6920d30a-7a73-45a8-bf2e-90aabe0aad10.gz
--------------------------------------------------------------------------------
/FMLab/$tf/10/c890a4fa-b780-4bc4-8546-08eb226f28d4.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/10/c890a4fa-b780-4bc4-8546-08eb226f28d4.gz
--------------------------------------------------------------------------------
/FMLab/$tf/10/e239beca-1906-4031-86e2-9709ad38c44e.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/10/e239beca-1906-4031-86e2-9709ad38c44e.gz
--------------------------------------------------------------------------------
/FMLab/$tf/10/f045ba2a-a7b3-453c-a9cf-ebc68b80d3c6.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/10/f045ba2a-a7b3-453c-a9cf-ebc68b80d3c6.gz
--------------------------------------------------------------------------------
/FMLab/$tf/12/338bcb7c-64b4-4274-879e-9a0716b597d5.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/12/338bcb7c-64b4-4274-879e-9a0716b597d5.gz
--------------------------------------------------------------------------------
/FMLab/$tf/12/cffcb19c-9be5-4281-bbc3-77da08d926dc.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/12/cffcb19c-9be5-4281-bbc3-77da08d926dc.gz
--------------------------------------------------------------------------------
/FMLab/$tf/12/d183ad7c-b15a-4c01-b586-9304f788c006.rw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/12/d183ad7c-b15a-4c01-b586-9304f788c006.rw
--------------------------------------------------------------------------------
/FMLab/$tf/12/fe6345fc-522e-42c6-bfff-ef57c74676a6.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/12/fe6345fc-522e-42c6-bfff-ef57c74676a6.gz
--------------------------------------------------------------------------------
/FMLab/$tf/13/6df4da5d-44d1-49e7-9406-98caa32b7f48.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/13/6df4da5d-44d1-49e7-9406-98caa32b7f48.gz
--------------------------------------------------------------------------------
/FMLab/$tf/13/7fa2e96d-8f32-458f-b2f7-7243631c9140.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/13/7fa2e96d-8f32-458f-b2f7-7243631c9140.gz
--------------------------------------------------------------------------------
/FMLab/$tf/13/7fa577fd-4f37-4da5-86a3-88c47cd54d66.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/13/7fa577fd-4f37-4da5-86a3-88c47cd54d66.gz
--------------------------------------------------------------------------------
/FMLab/$tf/13/88b41f3d-38fb-4aa4-a0a0-7640b8038c57.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/13/88b41f3d-38fb-4aa4-a0a0-7640b8038c57.gz
--------------------------------------------------------------------------------
/FMLab/$tf/13/cab05a9d-8fa0-41da-a68d-86b5bba87a1f.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/13/cab05a9d-8fa0-41da-a68d-86b5bba87a1f.gz
--------------------------------------------------------------------------------
/FMLab/$tf/14/230b847e-80cf-4895-979d-a63fda389f69.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/14/230b847e-80cf-4895-979d-a63fda389f69.gz
--------------------------------------------------------------------------------
/FMLab/$tf/14/2f08363e-e558-4043-8cd7-f9668d570513.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/14/2f08363e-e558-4043-8cd7-f9668d570513.gz
--------------------------------------------------------------------------------
/FMLab/$tf/14/991e6c0e-64e3-4957-9863-77840f7ef29c.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/14/991e6c0e-64e3-4957-9863-77840f7ef29c.gz
--------------------------------------------------------------------------------
/FMLab/$tf/14/c1c2c75e-35c1-4672-9598-908b89dc96d4.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/14/c1c2c75e-35c1-4672-9598-908b89dc96d4.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/4769b42f-2897-4084-8645-58a2ca2c1cf8.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/4769b42f-2897-4084-8645-58a2ca2c1cf8.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/576cdcbf-9d40-4fb8-803b-abe8f5deb00f.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/576cdcbf-9d40-4fb8-803b-abe8f5deb00f.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/bb4aac3f-7dd9-4084-a47f-04f530a89e69.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/bb4aac3f-7dd9-4084-a47f-04f530a89e69.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/bf0cc88f-766e-4ee4-953f-42e752258501.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/bf0cc88f-766e-4ee4-953f-42e752258501.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/caeb9e5f-4233-46ab-99c1-094cdfbb3e46.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/caeb9e5f-4233-46ab-99c1-094cdfbb3e46.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/ccbcdb2f-8710-4dd0-90e5-19fe171147d2.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/ccbcdb2f-8710-4dd0-90e5-19fe171147d2.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/f57743cf-99c9-4ef6-8d8c-b9c53e9e1c4f.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/f57743cf-99c9-4ef6-8d8c-b9c53e9e1c4f.gz
--------------------------------------------------------------------------------
/FMLab/$tf/15/fc3ce97f-a9ca-4939-879e-7b047c44f23a.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/15/fc3ce97f-a9ca-4939-879e-7b047c44f23a.gz
--------------------------------------------------------------------------------
/FMLab/$tf/2/06110bd2-084d-4c8b-964d-aac630227768.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/2/06110bd2-084d-4c8b-964d-aac630227768.gz
--------------------------------------------------------------------------------
/FMLab/$tf/2/4b3dc482-1ed7-421a-ba8d-d0a76d2fbad5.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/2/4b3dc482-1ed7-421a-ba8d-d0a76d2fbad5.gz
--------------------------------------------------------------------------------
/FMLab/$tf/2/5108e4d2-8aca-41f8-b85d-aebdf3f90f98.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/2/5108e4d2-8aca-41f8-b85d-aebdf3f90f98.gz
--------------------------------------------------------------------------------
/FMLab/$tf/2/514f6032-005e-49d9-8867-c28c093103ec.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/2/514f6032-005e-49d9-8867-c28c093103ec.gz
--------------------------------------------------------------------------------
/FMLab/$tf/2/54e0e862-b17f-45ef-8540-d29b95c7984b.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/2/54e0e862-b17f-45ef-8540-d29b95c7984b.gz
--------------------------------------------------------------------------------
/FMLab/$tf/2/ae6f73b2-b985-4edf-aa93-76eef3127ebd.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/2/ae6f73b2-b985-4edf-aa93-76eef3127ebd.gz
--------------------------------------------------------------------------------
/FMLab/$tf/2/e0a94a22-e548-440a-ba72-5ffb7dfb2005.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/2/e0a94a22-e548-440a-ba72-5ffb7dfb2005.gz
--------------------------------------------------------------------------------
/FMLab/$tf/3/dec4f863-7c2a-44e1-844d-407675224f03.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/3/dec4f863-7c2a-44e1-844d-407675224f03.gz
--------------------------------------------------------------------------------
/FMLab/$tf/3/f4875a63-c933-4612-b8b5-046164d181a7.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/3/f4875a63-c933-4612-b8b5-046164d181a7.gz
--------------------------------------------------------------------------------
/FMLab/$tf/4/418e4ee4-9ef6-47c6-8d1a-675cfd9b077e.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/4/418e4ee4-9ef6-47c6-8d1a-675cfd9b077e.gz
--------------------------------------------------------------------------------
/FMLab/$tf/4/6e13a834-578e-4360-a6d6-42ce671ce661.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/4/6e13a834-578e-4360-a6d6-42ce671ce661.gz
--------------------------------------------------------------------------------
/FMLab/$tf/4/baea85a4-6569-4641-8161-00d21d5fcc1d.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/4/baea85a4-6569-4641-8161-00d21d5fcc1d.gz
--------------------------------------------------------------------------------
/FMLab/$tf/5/99ffa485-a5e8-4d73-a22e-defc18d14662.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/5/99ffa485-a5e8-4d73-a22e-defc18d14662.gz
--------------------------------------------------------------------------------
/FMLab/$tf/5/dca24a05-c05d-46ba-bc00-87e1bfd6135c.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/5/dca24a05-c05d-46ba-bc00-87e1bfd6135c.gz
--------------------------------------------------------------------------------
/FMLab/$tf/6/17432966-7fb7-4c4b-a1c0-4de1b774b98e.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/6/17432966-7fb7-4c4b-a1c0-4de1b774b98e.gz
--------------------------------------------------------------------------------
/FMLab/$tf/6/777f1156-94cb-40b1-a9e8-87f2f10042d1.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/6/777f1156-94cb-40b1-a9e8-87f2f10042d1.gz
--------------------------------------------------------------------------------
/FMLab/$tf/6/dd7ddea6-4367-4298-a4fd-f347aeb7dd5f.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/6/dd7ddea6-4367-4298-a4fd-f347aeb7dd5f.gz
--------------------------------------------------------------------------------
/FMLab/$tf/6/fca62e46-c2a4-4434-a5bc-566b8c4aae95.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/6/fca62e46-c2a4-4434-a5bc-566b8c4aae95.gz
--------------------------------------------------------------------------------
/FMLab/$tf/7/1b53f527-af30-42c1-953b-bfb50c2b6b83.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/7/1b53f527-af30-42c1-953b-bfb50c2b6b83.gz
--------------------------------------------------------------------------------
/FMLab/$tf/7/ae332fc7-c75c-41b4-9d46-926279288b2b.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/7/ae332fc7-c75c-41b4-9d46-926279288b2b.gz
--------------------------------------------------------------------------------
/FMLab/$tf/8/09bb0848-94bd-4942-a276-f55ac614053e.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/8/09bb0848-94bd-4942-a276-f55ac614053e.gz
--------------------------------------------------------------------------------
/FMLab/$tf/8/220bdbb8-4f22-425b-a94e-5749d2603d03.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/8/220bdbb8-4f22-425b-a94e-5749d2603d03.gz
--------------------------------------------------------------------------------
/FMLab/$tf/8/813b2f98-3983-48ea-ab18-40cde25b7614.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/8/813b2f98-3983-48ea-ab18-40cde25b7614.gz
--------------------------------------------------------------------------------
/FMLab/$tf/8/ca3997d8-e6d1-4689-82ce-0aeaa58b077f.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/8/ca3997d8-e6d1-4689-82ce-0aeaa58b077f.gz
--------------------------------------------------------------------------------
/FMLab/$tf/8/cd6dd508-4613-4cd4-9949-48f97414f590.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/8/cd6dd508-4613-4cd4-9949-48f97414f590.gz
--------------------------------------------------------------------------------
/FMLab/$tf/9/0279f1a9-f7b3-4b22-8085-bd9b8244f52e.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/9/0279f1a9-f7b3-4b22-8085-bd9b8244f52e.gz
--------------------------------------------------------------------------------
/FMLab/$tf/9/25ddbd39-e3fa-4fe6-beb7-e7c9b2034b43.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/9/25ddbd39-e3fa-4fe6-beb7-e7c9b2034b43.gz
--------------------------------------------------------------------------------
/FMLab/$tf/9/39be00b9-89b0-4fcd-b2a2-8107af1e968c.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/9/39be00b9-89b0-4fcd-b2a2-8107af1e968c.gz
--------------------------------------------------------------------------------
/FMLab/$tf/9/8b281bd9-cec6-42d1-a75c-f29bb9becda2.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/9/8b281bd9-cec6-42d1-a75c-f29bb9becda2.gz
--------------------------------------------------------------------------------
/FMLab/$tf/9/bdb72cd9-30b6-4eb9-9d4a-d8c4f816f79e.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/9/bdb72cd9-30b6-4eb9-9d4a-d8c4f816f79e.gz
--------------------------------------------------------------------------------
/FMLab/$tf/localversion.tf1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/localversion.tf1
--------------------------------------------------------------------------------
/FMLab/$tf/localversion.tfb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/localversion.tfb
--------------------------------------------------------------------------------
/FMLab/$tf/pendingchanges.tf1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/pendingchanges.tf1
--------------------------------------------------------------------------------
/FMLab/$tf/pendingchanges.tfb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/$tf/pendingchanges.tfb
--------------------------------------------------------------------------------
/FMLab/$tf/properties.tf1:
--------------------------------------------------------------------------------
1 | <~ C : \ C : \ F M L a b \ $ t f l o c a l v e r s i o n p e n d i n g c h a n g e s H$ / D y n a m i c s E R P L a b s / F M T u t o r i a l / F M L a b C : \ F M L a b
--------------------------------------------------------------------------------
/FMLab/AxForm_FmtChargeType.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FmtChargeType
4 |
5 |
6 |
7 | classDeclaration
8 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | SimpleList
25 | 1.1
26 |
27 |
28 |
30 | ApplicationBar
31 | 429496729
32 | %1
33 | Yes
34 | ActionPane
35 | -1
36 |
38 |
39 | No
40 | No
41 |
42 |
44 | CustomFilterGroup
45 | CustomAndQuickFilters
46 | 1.1
47 | Group
48 | SizeToAvailable
49 |
51 |
52 |
53 | QuickFilter
54 |
55 | QuickFilterControl
56 |
57 |
58 |
59 | targetControlName
60 | String
61 |
62 |
63 | defaultColumnName
64 | String
65 |
66 |
67 |
68 |
69 |
70 | HorizontalLeft
71 | None
72 |
73 | Edit
74 |
75 |
77 | Grid
78 | 1431655764
79 | %1
80 | Grid
81 | -1
82 |
84 |
85 | No
86 | No
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/FMLab/AxForm_FmtCustomer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FmtCustomer
4 |
5 |
6 |
7 | classDeclaration
8 |
16 |
17 |
18 |
19 |
20 | FmtCustomer
21 |
22 |
23 | research
24 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | FmtCustomer
42 |
43 |
44 |
45 | Address
46 |
47 |
48 | AddressID
49 |
50 |
51 | AuditStatus
52 |
53 |
54 | CCExpiryDate
55 |
56 |
57 | CellPhone
58 |
59 |
60 | CreditCardNum
61 |
62 |
63 | CustGroup
64 |
65 |
66 | DriverLicense
67 |
68 |
69 | Email
70 |
71 |
72 | FirstName
73 |
74 |
75 | Image
76 |
77 |
78 | LastName
79 |
80 |
81 | LicenseImage
82 |
83 |
84 | Partition
85 |
86 |
87 | RecId
88 |
89 |
90 | TableId
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
103 | ApplicationBar
104 | 715827882
105 | %1
106 | Yes
107 | ActionPane
108 | -1
109 | 0
110 |
112 |
113 | No
114 | No
115 |
116 |
118 | GridDetailsTab
119 | No
120 | 1431655764
121 | %1
122 | 0
123 | Tab
124 | -1
125 | 0
126 |
128 |
129 |
131 | TabPageGrid
132 | 1610612733
133 | %1
134 | Auto
135 | TabPage
136 | -1
137 | Auto
138 |
140 |
141 |
143 | MainGrid
144 | 1431655764
145 | %1
146 | Grid
147 | -1
148 |
150 |
151 | GridDefaultActionButton
152 |
153 |
155 | GridDefaultActionButton
156 | Yes
157 | CommandButton
158 | No
159 |
161 | DetailsView
162 |
163 |
164 | Grid
165 | Auto
166 |
167 |
168 |
170 | TabPageDetails
171 | 1073741822
172 | %1
173 | Auto
174 | TabPage
175 | -1
176 | Auto
177 |
179 |
180 |
182 | TitleGroup
183 | 1073741822
184 | %1
185 | Group
186 | -1
187 |
189 |
190 |
192 | HeaderTitle
193 | 1431655764
194 | %1
195 | Yes
196 | String
197 | -1
198 |
200 |
201 |
202 |
203 | Auto
204 |
205 |
206 |
208 | DetailsBodyTab
209 | 1610612733
210 | %1
211 | Tab
212 | -1
213 |
215 |
216 |
218 | General
219 | 1431655764
220 | %1
221 | Auto
222 | TabPage
223 | -1
224 | Auto
225 |
227 |
228 | Auto
229 | @SYS2952
230 | Auto
231 |
232 |
233 | No
234 |
235 |
236 |
237 | Details
238 | Auto
239 |
240 |
241 |
242 | No
243 | No
244 |
245 |
246 |
247 |
248 |
--------------------------------------------------------------------------------
/FMLab/AxMenuItemDisplay_FMTCustomerWorkflow.CTP3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FMTCustomerWorkflow
4 |
5 |
--------------------------------------------------------------------------------
/FMLab/AxQuery_FMTCustomerWorkflowQuery.CTP3.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTCustomerWorkflowQuery
5 |
6 |
7 |
8 | classDeclaration
9 |
14 |
15 |
16 |
17 |
18 |
19 | FMTCustomer
20 | Yes
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | classDeclaration
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/FMLab/AxWorkflowCategory_FMTWorkflowCategory.CTP3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FMTWorkflowCategory
4 |
5 | Basic
6 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/ActivityMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ConnectorServiceApplication
8 | {
9 | public class ActivityMessage
10 | {
11 | ///
12 | /// Correlation-Id.
13 | ///
14 |
15 | public string CorrelationId { get; set; }
16 |
17 | ///
18 | /// Pop-Receipt.
19 | ///
20 |
21 | public string PopReceipt { get; set; }
22 |
23 | ///
24 | /// The content, if the content is completely contained within the queue message.
25 | ///
26 |
27 | public string Content { get; set; }
28 |
29 | ///
30 | /// The location to download, if the content is outside of the queue message.
31 | ///
32 |
33 | public Uri DownloadLocation { get; set; }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/ConnectorServiceApplication.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {78BE1A6C-63E2-4F41-A6E5-CA8D1DEDF12C}
8 | WinExe
9 | Properties
10 | ConnectorServiceApplication
11 | ConnectorServiceApplication
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | .\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
37 |
38 |
39 | .\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Form
60 |
61 |
62 | mainForm.cs
63 |
64 |
65 |
66 | mainForm.cs
67 |
68 |
69 |
70 |
71 |
72 |
73 |
80 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/FleetCustomerPlainText.xslt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | FirstName: LastName
6 |
7 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/Helper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.IdentityModel.Clients.ActiveDirectory;
7 | using System.Net.Http;
8 | using System.Net.Http.Headers;
9 | using System.IO;
10 | using System.Net.Http.Formatting;
11 | using System.Configuration;
12 |
13 | namespace ConnectorServiceApplication
14 | {
15 | class Helper
16 | {
17 | string authenticationHeader = "";
18 | public string AuthenticationHeader
19 | {
20 | get
21 | {
22 | return authenticationHeader;
23 | }
24 | }
25 |
26 |
27 | public Helper(string clientId, string clientSecret)
28 | {
29 | //authentication string details
30 | UriBuilder uri = new UriBuilder(ConfigurationManager.AppSettings["Azure auth Uri"]);
31 | uri.Path = ConfigurationManager.AppSettings["Aad Tenant"];
32 |
33 | AuthenticationContext authenticationContext = new AuthenticationContext(uri.ToString());
34 | ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
35 | AuthenticationResult authenticationResult = authenticationContext.AcquireToken(ConfigurationManager.AppSettings["Rainier Service Prinicipal"], clientCred);
36 |
37 | authenticationHeader = authenticationResult.CreateAuthorizationHeader();
38 | }
39 |
40 |
41 | public HttpResponseMessage SendPostRequest(Uri uri, string authenticationHeader, string body, ActivityMessage message)
42 | {
43 |
44 | using (HttpClientHandler handler = new HttpClientHandler() { UseCookies = false })
45 | {
46 | using (HttpClient webClient = new HttpClient(handler))
47 | {
48 | webClient.DefaultRequestHeaders.Authorization = ParseAuthenticationHeader(authenticationHeader);
49 |
50 | HttpResponseMessage response;
51 |
52 | if (body != null)
53 | {
54 | //convert string into memorystream to be passed in the post request
55 | byte[] bytes = Encoding.ASCII.GetBytes(body);
56 | MemoryStream memStream = new MemoryStream(bytes);
57 |
58 | using (StreamContent content = new StreamContent(memStream))
59 | {
60 | response = webClient.PostAsync(uri, content).Result;
61 | }
62 | }
63 | else
64 | {
65 | response = webClient.PostAsJsonAsync(uri.ToString(), message).Result;
66 | }
67 |
68 | return response;
69 | }
70 | }
71 | }
72 |
73 | public HttpResponseMessage SendRequest(HttpRequestMessage request)
74 | {
75 | using (HttpClientHandler handler = new HttpClientHandler() { UseCookies = false })
76 | {
77 | using (HttpClient webClient = new HttpClient(handler))
78 | {
79 | HttpResponseMessage response = webClient.SendAsync(request).Result;
80 | return response;
81 | }
82 | }
83 | }
84 |
85 |
86 |
87 | private static AuthenticationHeaderValue ParseAuthenticationHeader(string authenticationHeader)
88 | {
89 | string[] split = authenticationHeader.Split(' ');
90 | string scheme = split[0];
91 | string parameter = split[1];
92 | return new AuthenticationHeaderValue(scheme, parameter);
93 | }
94 |
95 |
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace ConnectorServiceApplication
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// The main entry point for the application.
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new mainForm());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/mainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ConnectorServiceApplication
2 | {
3 | partial class mainForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.groupBox1 = new System.Windows.Forms.GroupBox();
32 | this.txtBoxTenant = new System.Windows.Forms.TextBox();
33 | this.label8 = new System.Windows.Forms.Label();
34 | this.txtBoxSecret = new System.Windows.Forms.TextBox();
35 | this.label2 = new System.Windows.Forms.Label();
36 | this.txtBoxClientId = new System.Windows.Forms.TextBox();
37 | this.label1 = new System.Windows.Forms.Label();
38 | this.groupBox2 = new System.Windows.Forms.GroupBox();
39 | this.btnEnqueue = new System.Windows.Forms.Button();
40 | this.label4 = new System.Windows.Forms.Label();
41 | this.richTextEnqueue = new System.Windows.Forms.RichTextBox();
42 | this.txtBoxInActivity = new System.Windows.Forms.TextBox();
43 | this.label3 = new System.Windows.Forms.Label();
44 | this.groupBox3 = new System.Windows.Forms.GroupBox();
45 | this.btnDequeue = new System.Windows.Forms.Button();
46 | this.label5 = new System.Windows.Forms.Label();
47 | this.richTxtDequeue = new System.Windows.Forms.RichTextBox();
48 | this.txtBoxOutActivity = new System.Windows.Forms.TextBox();
49 | this.label6 = new System.Windows.Forms.Label();
50 | this.txtBoxBaseUri = new System.Windows.Forms.TextBox();
51 | this.label7 = new System.Windows.Forms.Label();
52 | this.richTxtLog = new System.Windows.Forms.RichTextBox();
53 | this.groupBox1.SuspendLayout();
54 | this.groupBox2.SuspendLayout();
55 | this.groupBox3.SuspendLayout();
56 | this.SuspendLayout();
57 | //
58 | // groupBox1
59 | //
60 | this.groupBox1.Controls.Add(this.txtBoxTenant);
61 | this.groupBox1.Controls.Add(this.label8);
62 | this.groupBox1.Controls.Add(this.txtBoxSecret);
63 | this.groupBox1.Controls.Add(this.label2);
64 | this.groupBox1.Controls.Add(this.txtBoxClientId);
65 | this.groupBox1.Controls.Add(this.label1);
66 | this.groupBox1.ForeColor = System.Drawing.Color.White;
67 | this.groupBox1.Location = new System.Drawing.Point(12, 18);
68 | this.groupBox1.Name = "groupBox1";
69 | this.groupBox1.Size = new System.Drawing.Size(912, 81);
70 | this.groupBox1.TabIndex = 0;
71 | this.groupBox1.TabStop = false;
72 | this.groupBox1.Text = "Azure Client Registration Details ";
73 | //
74 | // txtBoxTenant
75 | //
76 | this.txtBoxTenant.Location = new System.Drawing.Point(96, 48);
77 | this.txtBoxTenant.Name = "txtBoxTenant";
78 | this.txtBoxTenant.ReadOnly = true;
79 | this.txtBoxTenant.Size = new System.Drawing.Size(277, 20);
80 | this.txtBoxTenant.TabIndex = 5;
81 | //
82 | // label8
83 | //
84 | this.label8.AutoSize = true;
85 | this.label8.Location = new System.Drawing.Point(10, 48);
86 | this.label8.Name = "label8";
87 | this.label8.Size = new System.Drawing.Size(71, 15);
88 | this.label8.TabIndex = 4;
89 | this.label8.Text = "AAD Tenant";
90 | //
91 | // txtBoxSecret
92 | //
93 | this.txtBoxSecret.Location = new System.Drawing.Point(622, 19);
94 | this.txtBoxSecret.Name = "txtBoxSecret";
95 | this.txtBoxSecret.ReadOnly = true;
96 | this.txtBoxSecret.Size = new System.Drawing.Size(277, 20);
97 | this.txtBoxSecret.TabIndex = 3;
98 | this.txtBoxSecret.Text = "Client Secret key";
99 | //
100 | // label2
101 | //
102 | this.label2.AutoSize = true;
103 | this.label2.Location = new System.Drawing.Point(519, 22);
104 | this.label2.Name = "label2";
105 | this.label2.Size = new System.Drawing.Size(97, 15);
106 | this.label2.TabIndex = 2;
107 | this.label2.Text = "Client Secret key";
108 | //
109 | // txtBoxClientId
110 | //
111 | this.txtBoxClientId.Location = new System.Drawing.Point(235, 19);
112 | this.txtBoxClientId.Name = "txtBoxClientId";
113 | this.txtBoxClientId.ReadOnly = true;
114 | this.txtBoxClientId.Size = new System.Drawing.Size(277, 20);
115 | this.txtBoxClientId.TabIndex = 1;
116 | //
117 | // label1
118 | //
119 | this.label1.AutoSize = true;
120 | this.label1.Location = new System.Drawing.Point(10, 22);
121 | this.label1.Name = "label1";
122 | this.label1.Size = new System.Drawing.Size(219, 15);
123 | this.label1.TabIndex = 0;
124 | this.label1.Text = "Registered Client Id (from Azure Portal)";
125 | //
126 | // groupBox2
127 | //
128 | this.groupBox2.Controls.Add(this.btnEnqueue);
129 | this.groupBox2.Controls.Add(this.label4);
130 | this.groupBox2.Controls.Add(this.richTextEnqueue);
131 | this.groupBox2.Controls.Add(this.txtBoxInActivity);
132 | this.groupBox2.Controls.Add(this.label3);
133 | this.groupBox2.ForeColor = System.Drawing.Color.White;
134 | this.groupBox2.Location = new System.Drawing.Point(12, 134);
135 | this.groupBox2.Name = "groupBox2";
136 | this.groupBox2.Size = new System.Drawing.Size(912, 275);
137 | this.groupBox2.TabIndex = 1;
138 | this.groupBox2.TabStop = false;
139 | this.groupBox2.Text = "Enqueue a message";
140 | //
141 | // btnEnqueue
142 | //
143 | this.btnEnqueue.ForeColor = System.Drawing.Color.Black;
144 | this.btnEnqueue.Location = new System.Drawing.Point(712, 28);
145 | this.btnEnqueue.Name = "btnEnqueue";
146 | this.btnEnqueue.Size = new System.Drawing.Size(150, 23);
147 | this.btnEnqueue.TabIndex = 6;
148 | this.btnEnqueue.Text = "Enqueue Message";
149 | this.btnEnqueue.UseVisualStyleBackColor = true;
150 | this.btnEnqueue.Click += new System.EventHandler(this.btnEnqueue_Click);
151 | //
152 | // label4
153 | //
154 | this.label4.AutoSize = true;
155 | this.label4.Location = new System.Drawing.Point(10, 68);
156 | this.label4.Name = "label4";
157 | this.label4.Size = new System.Drawing.Size(58, 15);
158 | this.label4.TabIndex = 5;
159 | this.label4.Text = "Message";
160 | //
161 | // richTextEnqueue
162 | //
163 | this.richTextEnqueue.BackColor = System.Drawing.SystemColors.Info;
164 | this.richTextEnqueue.Font = new System.Drawing.Font("Segoe UI", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
165 | this.richTextEnqueue.Location = new System.Drawing.Point(83, 65);
166 | this.richTextEnqueue.Name = "richTextEnqueue";
167 | this.richTextEnqueue.Size = new System.Drawing.Size(816, 199);
168 | this.richTextEnqueue.TabIndex = 4;
169 | this.richTextEnqueue.Text = "";
170 | //
171 | // txtBoxInActivity
172 | //
173 | this.txtBoxInActivity.Location = new System.Drawing.Point(83, 30);
174 | this.txtBoxInActivity.Name = "txtBoxInActivity";
175 | this.txtBoxInActivity.Size = new System.Drawing.Size(277, 20);
176 | this.txtBoxInActivity.TabIndex = 3;
177 | //
178 | // label3
179 | //
180 | this.label3.AutoSize = true;
181 | this.label3.Location = new System.Drawing.Point(10, 33);
182 | this.label3.Name = "label3";
183 | this.label3.Size = new System.Drawing.Size(55, 15);
184 | this.label3.TabIndex = 2;
185 | this.label3.Text = "Activity Id";
186 | //
187 | // groupBox3
188 | //
189 | this.groupBox3.Controls.Add(this.btnDequeue);
190 | this.groupBox3.Controls.Add(this.label5);
191 | this.groupBox3.Controls.Add(this.richTxtDequeue);
192 | this.groupBox3.Controls.Add(this.txtBoxOutActivity);
193 | this.groupBox3.Controls.Add(this.label6);
194 | this.groupBox3.ForeColor = System.Drawing.Color.White;
195 | this.groupBox3.Location = new System.Drawing.Point(12, 415);
196 | this.groupBox3.Name = "groupBox3";
197 | this.groupBox3.Size = new System.Drawing.Size(912, 275);
198 | this.groupBox3.TabIndex = 2;
199 | this.groupBox3.TabStop = false;
200 | this.groupBox3.Text = "Dequeue message";
201 | //
202 | // btnDequeue
203 | //
204 | this.btnDequeue.ForeColor = System.Drawing.Color.Black;
205 | this.btnDequeue.Location = new System.Drawing.Point(728, 28);
206 | this.btnDequeue.Name = "btnDequeue";
207 | this.btnDequeue.Size = new System.Drawing.Size(150, 23);
208 | this.btnDequeue.TabIndex = 6;
209 | this.btnDequeue.Text = "Dequeue Message";
210 | this.btnDequeue.UseVisualStyleBackColor = true;
211 | this.btnDequeue.Click += new System.EventHandler(this.btnDequeue_Click);
212 | //
213 | // label5
214 | //
215 | this.label5.AutoSize = true;
216 | this.label5.Location = new System.Drawing.Point(10, 68);
217 | this.label5.Name = "label5";
218 | this.label5.Size = new System.Drawing.Size(58, 15);
219 | this.label5.TabIndex = 5;
220 | this.label5.Text = "Message";
221 | //
222 | // richTxtDequeue
223 | //
224 | this.richTxtDequeue.BackColor = System.Drawing.SystemColors.Info;
225 | this.richTxtDequeue.Location = new System.Drawing.Point(83, 65);
226 | this.richTxtDequeue.Name = "richTxtDequeue";
227 | this.richTxtDequeue.Size = new System.Drawing.Size(816, 199);
228 | this.richTxtDequeue.TabIndex = 4;
229 | this.richTxtDequeue.Text = "";
230 | //
231 | // txtBoxOutActivity
232 | //
233 | this.txtBoxOutActivity.Location = new System.Drawing.Point(83, 30);
234 | this.txtBoxOutActivity.Name = "txtBoxOutActivity";
235 | this.txtBoxOutActivity.Size = new System.Drawing.Size(277, 20);
236 | this.txtBoxOutActivity.TabIndex = 3;
237 | //
238 | // label6
239 | //
240 | this.label6.AutoSize = true;
241 | this.label6.Location = new System.Drawing.Point(10, 33);
242 | this.label6.Name = "label6";
243 | this.label6.Size = new System.Drawing.Size(55, 15);
244 | this.label6.TabIndex = 2;
245 | this.label6.Text = "Activity Id";
246 | //
247 | // txtBoxBaseUri
248 | //
249 | this.txtBoxBaseUri.Location = new System.Drawing.Point(200, 108);
250 | this.txtBoxBaseUri.Name = "txtBoxBaseUri";
251 | this.txtBoxBaseUri.Size = new System.Drawing.Size(479, 20);
252 | this.txtBoxBaseUri.TabIndex = 5;
253 | this.txtBoxBaseUri.Text = "Dynamics base URL for your org";
254 | //
255 | // label7
256 | //
257 | this.label7.AutoSize = true;
258 | this.label7.Location = new System.Drawing.Point(11, 108);
259 | this.label7.Name = "label7";
260 | this.label7.Size = new System.Drawing.Size(183, 15);
261 | this.label7.TabIndex = 4;
262 | this.label7.Text = "Dynamics base URL for your org";
263 | //
264 | // richTxtLog
265 | //
266 | this.richTxtLog.BackColor = System.Drawing.SystemColors.ControlLight;
267 | this.richTxtLog.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
268 | this.richTxtLog.Location = new System.Drawing.Point(930, 60);
269 | this.richTxtLog.Name = "richTxtLog";
270 | this.richTxtLog.Size = new System.Drawing.Size(528, 619);
271 | this.richTxtLog.TabIndex = 6;
272 | this.richTxtLog.Text = "";
273 | //
274 | // mainForm
275 | //
276 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
277 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
278 | this.BackColor = System.Drawing.Color.Black;
279 | this.ClientSize = new System.Drawing.Size(1470, 701);
280 | this.Controls.Add(this.richTxtLog);
281 | this.Controls.Add(this.txtBoxBaseUri);
282 | this.Controls.Add(this.label7);
283 | this.Controls.Add(this.groupBox3);
284 | this.Controls.Add(this.groupBox2);
285 | this.Controls.Add(this.groupBox1);
286 | this.ForeColor = System.Drawing.Color.White;
287 | this.Name = "mainForm";
288 | this.Text = "Connector Service - Client Application";
289 | this.groupBox1.ResumeLayout(false);
290 | this.groupBox1.PerformLayout();
291 | this.groupBox2.ResumeLayout(false);
292 | this.groupBox2.PerformLayout();
293 | this.groupBox3.ResumeLayout(false);
294 | this.groupBox3.PerformLayout();
295 | this.ResumeLayout(false);
296 | this.PerformLayout();
297 |
298 | }
299 |
300 | #endregion
301 |
302 | private System.Windows.Forms.GroupBox groupBox1;
303 | private System.Windows.Forms.Label label1;
304 | private System.Windows.Forms.TextBox txtBoxSecret;
305 | private System.Windows.Forms.Label label2;
306 | private System.Windows.Forms.TextBox txtBoxClientId;
307 | private System.Windows.Forms.GroupBox groupBox2;
308 | private System.Windows.Forms.TextBox txtBoxInActivity;
309 | private System.Windows.Forms.Label label3;
310 | private System.Windows.Forms.RichTextBox richTextEnqueue;
311 | private System.Windows.Forms.Button btnEnqueue;
312 | private System.Windows.Forms.Label label4;
313 | private System.Windows.Forms.GroupBox groupBox3;
314 | private System.Windows.Forms.Button btnDequeue;
315 | private System.Windows.Forms.Label label5;
316 | private System.Windows.Forms.RichTextBox richTxtDequeue;
317 | private System.Windows.Forms.TextBox txtBoxOutActivity;
318 | private System.Windows.Forms.Label label6;
319 | private System.Windows.Forms.TextBox txtBoxBaseUri;
320 | private System.Windows.Forms.Label label7;
321 | private System.Windows.Forms.RichTextBox richTxtLog;
322 | private System.Windows.Forms.Label label8;
323 | private System.Windows.Forms.TextBox txtBoxTenant;
324 | }
325 | }
326 |
327 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/mainForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using System.Net.Http;
11 | using System.Configuration;
12 |
13 | namespace ConnectorServiceApplication
14 | {
15 | public partial class mainForm : Form
16 | {
17 |
18 | public mainForm()
19 | {
20 | InitializeComponent();
21 |
22 | txtBoxBaseUri.Text = ConfigurationManager.AppSettings["Rainier Uri"];
23 | txtBoxClientId.Text = ConfigurationManager.AppSettings["Azure Client Id"];
24 | txtBoxSecret.Text = ConfigurationManager.AppSettings[ "Azure Client Secret"];
25 | txtBoxTenant.Text = ConfigurationManager.AppSettings["Aad Tenant"];
26 | }
27 |
28 | private void btnEnqueue_Click(object sender, EventArgs e)
29 | {
30 | if (richTextEnqueue.Text.Length == 0)
31 | return;
32 |
33 | Cursor.Current = Cursors.WaitCursor;
34 |
35 | //authenticate
36 | Helper helper = new Helper(txtBoxClientId.Text, txtBoxSecret.Text);
37 |
38 | //remove the unwanted curly braces
39 | txtBoxInActivity.Text = txtBoxInActivity.Text.Replace("{", "");
40 | txtBoxInActivity.Text = txtBoxInActivity.Text.Replace("}", "");
41 |
42 | //access the Connector API
43 | UriBuilder enqueueUri = new UriBuilder(txtBoxBaseUri.Text);
44 | enqueueUri.Path = "api/connector/Enqueue/" + txtBoxInActivity.Text;
45 |
46 | helper.SendPostRequest(enqueueUri.Uri, helper.AuthenticationHeader, richTextEnqueue.Text, null);
47 | richTxtLog.AppendText ("Message Enqueued: " + enqueueUri.Uri + "\u2028");
48 |
49 | Cursor.Current = Cursors.Default;
50 | }
51 |
52 |
53 | private void btnDequeue_Click(object sender, EventArgs e)
54 | {
55 | if (txtBoxOutActivity.Text.Length == 0)
56 | return;
57 |
58 | Cursor.Current = Cursors.WaitCursor;
59 |
60 | //authenticate
61 | Helper helper = new Helper(txtBoxClientId.Text, txtBoxSecret.Text);
62 |
63 | //remove the unwanted curly braces
64 | txtBoxOutActivity.Text = txtBoxOutActivity.Text.Replace("{", "");
65 | txtBoxOutActivity.Text = txtBoxOutActivity.Text.Replace("}", "");
66 |
67 | //access the Connector API
68 | UriBuilder dequeueUri = new UriBuilder(txtBoxBaseUri.Text);
69 | dequeueUri.Path = "api/connector/dequeue/" + txtBoxOutActivity.Text;
70 |
71 |
72 | //send a request to get the next queue message
73 | HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, dequeueUri.Uri);
74 | request.Headers.Add("Authorization", helper.AuthenticationHeader);
75 | HttpResponseMessage response = helper.SendRequest(request);
76 |
77 | //read the response
78 | ActivityMessage responseMessage = response.Content.ReadAsAsync().Result;
79 | if (responseMessage == null)
80 | {
81 | MessageBox.Show("No more messages in the queue");
82 | return;
83 | }
84 |
85 |
86 | //read the downloadlocation and make a blob request
87 | request = new HttpRequestMessage(HttpMethod.Get, responseMessage.DownloadLocation.ToString());
88 | request.Headers.Add("Authorization", helper.AuthenticationHeader);
89 |
90 | //send a request to get the actual content from the blob storage
91 | HttpResponseMessage blobResponse = helper.SendRequest(request);
92 | richTxtDequeue.Text = blobResponse.Content.ReadAsStringAsync().Result;
93 |
94 | //ack the message
95 | UriBuilder ackUri= new UriBuilder(txtBoxBaseUri.Text);
96 | ackUri.Path = "api/connector/ack/" + txtBoxOutActivity.Text;
97 | helper.SendPostRequest(ackUri.Uri, helper.AuthenticationHeader, null, responseMessage);
98 |
99 | richTxtLog.AppendText ("Message dequeued and acked. MessageId: " + responseMessage.CorrelationId + "\u2028");
100 |
101 | Cursor.Current = Cursors.Default;
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/mainForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/FMLab/ConnectorClientApplication/uploadFMCustomer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FMLab/DemoBP.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/DemoBP.zip
--------------------------------------------------------------------------------
/FMLab/DriversLicenseChecker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace DriversLicenseEvaluator
8 | {
9 | using Dynamics.AX.Application;
10 | using Microsoft.Dynamics.AX.Framework.Linq.Data;
11 | using Microsoft.Dynamics.Ax.Xpp;
12 |
13 | public class DriversLicenseChecker
14 | {
15 | public static bool CheckDriversLicense(long customerId)
16 | {
17 | // Use LINQ to get back to the information about the
18 | // license number
19 | FMCustomer customer;
20 | QueryProvider provider = new AXQueryProvider(null);
21 | var customers = new QueryCollection(provider);
22 |
23 | // Build the query (but do not execute it)
24 | var query = from c in customers
25 | where c.RecId == customerId
26 | select c;
27 |
28 | // Execute the query:
29 | customer = query.FirstOrDefault();
30 | if (customer == null)
31 | {
32 | throw new ArgumentException
33 | ("The customerId does not designate a customer");
34 | }
35 |
36 | // or, much more succinctly:
37 | // customer = customers.Single(c => c.RecId == customerId);
38 |
39 | if (string.IsNullOrEmpty(customer.DriverLicense))
40 | {
41 | // No driver's license was recorded. Veto the rental.
42 | return false;
43 | }
44 |
45 | // Call the DOT web service to validate the license number.
46 | // This is not practical for this lab, because all the service providers
47 | // charge for this service. Instead, just assume that any license number
48 | // that contains the sequence "89" is valid.
49 | // In the demo data, this is true for Adrian Lannin,
50 | // but not for Phil Spencer.
51 | return customer.DriverLicense.Contains("89");
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/FMLab/DynamicsAX.ExcelManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 61bcc63f-b860-4280-8280-3e4fb5ea7726
6 | 1.0.0.0
7 | Microsoft Corporation
8 | en-US
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ReadWriteDocument
29 |
30 |
--------------------------------------------------------------------------------
/FMLab/EDT/AxEdt_FMTCCExpiryDate.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTCCExpiryDate
5 | Calendar
6 | @SYS78674
7 |
8 | FMTCustomer
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/FMLab/EDT/AxEdt_FMTChargeTypeId.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTChargeTypeId
5 | @SYS78674
6 |
7 |
8 |
9 |
10 | 20
11 |
--------------------------------------------------------------------------------
/FMLab/EDT/AxEdt_FMTCreditCardNum.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTCreditCardNum
5 |
6 |
7 |
8 | 20
9 |
--------------------------------------------------------------------------------
/FMLab/EDT/AxEdt_FMTCustomerRecId.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTCustomerRecId
5 | RefRecId
6 | @SYS78674
7 |
8 | FMTCustomer
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/FMLab/EDT/AxEdt_FMTDescription.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTDescription
5 | @SYS78674
6 |
7 |
8 |
9 |
10 | 255
11 |
--------------------------------------------------------------------------------
/FMLab/EDT/AxEdt_FMTDriversLicense.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTDriversLicense
5 | @SYS78674
6 |
7 |
8 |
9 |
10 | 20
11 |
--------------------------------------------------------------------------------
/FMLab/EDT/AxEdt_FMTName.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | FMTName
5 | @SYS78674
6 |
7 | FMTCustomer
8 |
9 |
10 |
11 | 50
12 |
--------------------------------------------------------------------------------
/FMLab/FMTutorialDataModel.axpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/FMTutorialDataModel.axpp
--------------------------------------------------------------------------------
/FMLab/Lab10-1/Adding BI to workspaces.axpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/Lab10-1/Adding BI to workspaces.axpp
--------------------------------------------------------------------------------
/FMLab/Lab10-2/Add contextual BI to a form - After Lab.axpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/Lab10-2/Add contextual BI to a form - After Lab.axpp
--------------------------------------------------------------------------------
/FMLab/Lab10-2/Add contextual BI to a form - Before Lab.axpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/Lab10-2/Add contextual BI to a form - Before Lab.axpp
--------------------------------------------------------------------------------
/FMLab/Lab10-2/Add contextual BI to a form.axpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/Lab10-2/Add contextual BI to a form.axpp
--------------------------------------------------------------------------------
/FMLab/Lab10-2/FMBILabHelper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FMBILabHelper
4 |
5 |
16 |
17 |
18 | FMBILab_ExecuteQuery
19 |
21 | /// Helper method to Read data from an Aggregate Data entity and move to the Temp table required by Lab 10.2
22 | ///
23 | ///
24 |
25 | public static void FMBILab_ExecuteQuery(str vehicleMakeParameter, TmpDBBIFMRevenueByVehicleModelByMonth tempTable)
26 | {
27 | try
28 | {
29 |
30 | // Get the aggregate query behind the existing Aggregate data entity FMBIRevenueByVehicleModel
31 | AggregateQuery aq = AggregateQueryRun::QueryFromAggregateDataEntity(tablestr(FMBIRevenueByVehicleModel));
32 |
33 | if (aq != null)
34 | {
35 |
36 | // Defne the filter expression using the Vehicle make
37 | LevelExpression allMakes = new LevelExpression(dimensionhierarchylevelstr("FMAggregateMeasurements/FMVehicle/VehicleMake/VehicleMake"));
38 | LogicalExpression currentMakeFilter = new Microsoft.Dynamics.AX.Framework.Analytics.AggregateQuery.QueryModel.Core.Exists(new MemberExpression(allMakes, vehicleMakeParameter));
39 |
40 | // Add the filter condition to the orignal query
41 | aq.AddSelect(new FilterExpression(SetExpression::ALL, currentMakeFilter));
42 |
43 | // Since the Aggregate Data entity does not have a month column, We need to add months to the existing query
44 | // we can add additional dimension attributes and measures. But we can't remove existing ones at present
45 | SetExpression allMonths = new LevelExpression(dimensionhierarchylevelstr("FMAggregateMeasurements/RentalStartDate/Quarter/Quarter"));
46 |
47 | /// Add the new Set to the orignal query as another column. "As" is an alias that we will provide to this column
48 | /// We don't need to provide Aliases for fields sourced from an Aggregate Data entity
49 | aq.AddSelect(allMonths.As("Quarter"));
50 |
51 | /// Create a QueryRun object using the query we have constructed. QueryRun objet enables us to retrieve data
52 | AggregateQueryRun queryRun = new AggregateQueryRun(aq);
53 |
54 | /// Instead of iterating in a loop and reading data from the QueryRun object, we can Bulk move data into the destination Table
55 | /// define the mappins between the dataset of the query result and our target table that we want to populate
56 | QueryResultToDatasourceColumnMappings mappings = new QueryResultToDatasourceColumnMappings();
57 | mappings.AddMapping("TotalRevenue", fieldstr(TmpDBBIFMRevenueByVehicleModelByMonth, TotalRevenue));
58 | mappings.AddMapping("NumRentals", fieldstr(TmpDBBIFMRevenueByVehicleModelByMonth, NumRentals));
59 | mappings.AddMapping("VehicleModel", fieldstr(TmpDBBIFMRevenueByVehicleModelByMonth, VehicleModel));
60 | mappings.AddMapping("Quarter", fieldstr(TmpDBBIFMRevenueByVehicleModelByMonth, RentalMonth));
61 |
62 | // execute the query and populate the target table as a bulk move
63 | queryRun.RunAndPopulate(tempTable, mappings);
64 | }
65 | }
66 | catch (Exception::CLRError)
67 | {
68 | SRSProxy::handleClrException(Exception::Error);
69 | }
70 | }
71 |
72 | ]]>
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/FMLab/Lab10-2/FMBIRevenueByVehicleModel.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FMBIRevenueByVehicleModel
4 |
5 |
10 |
11 |
12 |
13 | DataSource
14 | FMAggregateMeasurements
15 |
16 |
17 |
18 |
19 | AutoReport
20 |
21 |
22 |
23 | AutoLookup
24 |
25 |
26 |
27 | AutoIdentification
28 | Yes
29 |
30 |
31 |
32 | AutoSummary
33 |
34 |
35 |
36 | AutoBrowse
37 |
38 |
39 |
40 |
41 |
43 | NumRentals
44 | BIRCount
45 | NoRentals
46 | FMRentalCharges
47 |
48 |
50 | TotalRevenue
51 | FMExtendedAmount
52 | TotalRevenue
53 | FMRentalCharges
54 |
55 |
57 | VehicleModel
58 | VehicleModel
59 | FMVehicle
60 | FMVehicleModelId
61 | FMRentalCharges
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/FMLab/Lab10-2/TmpDBBIFMRevenueByVehicleModelByMonth.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | TmpDBBIFMRevenueByVehicleModelByMonth
4 |
5 |
10 |
11 |
12 | No
13 | TempDB
14 |
15 |
16 |
17 | AutoReport
18 |
19 |
20 |
21 | AutoLookup
22 |
23 |
24 |
25 | AutoIdentification
26 | Yes
27 |
28 |
29 |
30 | AutoSummary
31 |
32 |
33 |
34 | AutoBrowse
35 |
36 |
37 |
38 |
39 |
41 | TotalRevenue
42 | FMExtendedAmount
43 |
44 |
46 | NumRentals
47 | FMQuantity
48 |
49 |
51 | VehicleModel
52 | FMVehicleModelId
53 | 20
54 |
55 |
57 | RentalMonth
58 | 30
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Relation1
67 | FMVehicleModel
68 | ExactlyOne
69 |
70 |
72 | VehicleModel
73 | VehicleModel
74 | Model
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/FMLab/Lab10-3/FMRentalDetailsReport.axpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/FMLab/01130ec5ff2c0c5ff26aaba52743b4e4ec0d1174/FMLab/Lab10-3/FMRentalDetailsReport.axpp
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/AuthenticationHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.ServiceModel;
6 | using Microsoft.IdentityModel.Protocols.WSTrust;
7 | using System.IdentityModel.Tokens;
8 | using WindowsForms = System.Windows.Forms;
9 | using Microsoft.IdentityModel.Tokens.Saml2;
10 | using Microsoft.IdentityModel.Tokens.Saml11;
11 | using System.IO;
12 | using System.Xml;
13 | using System.Net;
14 | using System.Net.Security;
15 | using System.Security.Cryptography.X509Certificates;
16 | using System.Globalization;
17 | using System.Configuration;
18 | using System.Diagnostics;
19 | using ODataConsoleApplication.ServiceReference1;
20 | using System.Data.Services.Client;
21 |
22 | namespace ODataConsoleApplication
23 | {
24 | internal class AuthenticationHelper
25 | {
26 | const string aosUrl = "https://usncax1aos.cloud.onebox.dynamics.com/";
27 | private static String cookies;
28 |
29 | internal static string PerformAuthentication(Resources context)
30 | {
31 |
32 | AcsResponse param = new AcsResponse();
33 | BrowserForm browserForm = new BrowserForm(aosUrl, param);
34 | WindowsForms.Application.Run(browserForm);
35 | // Debug.Assert(!browserForm.NavigationCanceled, "Unable to perform authentication to AOS");
36 |
37 | HttpWebRequest httpRequest;
38 | HttpWebResponse httpResponse;
39 | CookieContainer cookieContainer = new CookieContainer();
40 |
41 | httpRequest = (HttpWebRequest)WebRequest.Create(aosUrl);
42 | httpRequest.Method = "POST";
43 | httpRequest.ContentType = "application/x-www-form-urlencoded";
44 |
45 | //
46 | // Authentication was done by using the hostname URI and not
47 | // full request URI. Hence, we should not let autoredirect
48 | // happen.
49 | //
50 |
51 | httpRequest.AllowAutoRedirect = false;
52 | httpRequest.CookieContainer = cookieContainer;
53 |
54 | StreamWriter writer = new StreamWriter(httpRequest.GetRequestStream(), Encoding.ASCII);
55 | writer.Write(param.GetAcsResponseString());
56 | writer.Flush();
57 | writer.Close();
58 |
59 | httpResponse = (HttpWebResponse)httpRequest.GetResponse();
60 | httpResponse.Close();
61 |
62 | StringBuilder retval = new StringBuilder();
63 |
64 | CookieCollection cookiesCollection = cookieContainer.GetCookies(new Uri(aosUrl));
65 |
66 | if (cookiesCollection.Count > 0)
67 | {
68 | foreach (Cookie c in cookiesCollection)
69 | {
70 | retval.AppendFormat("{0}={1}; ", c.Name, c.Value);
71 | }
72 |
73 | //Remove the trailing "; "
74 | retval.Remove(retval.Length - 2, 2);
75 | }
76 |
77 | cookies = retval.ToString();
78 |
79 | context.SendingRequest += new EventHandler(OnSendingRequest);
80 |
81 | return cookies;
82 | }
83 |
84 | public static void OnSendingRequest(object sender, SendingRequestEventArgs e)
85 | {
86 | // Add the cookie to the cookie header to authenticate call to service
87 | e.RequestHeaders.Add(HttpRequestHeader.Cookie, cookies);
88 | }
89 |
90 | }
91 | }
92 |
93 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/BrowserForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using System.Xml;
10 | using System.Web;
11 | using System.Diagnostics;
12 | using System.Globalization;
13 | using System.Text.RegularExpressions;
14 |
15 | namespace ODataConsoleApplication
16 | {
17 | public partial class BrowserForm : Form
18 | {
19 | public BrowserForm(String url, AcsResponse param)
20 | {
21 | SetUrl(url);
22 | SetAcsResponseParam(param);
23 | InitializeComponent();
24 | }
25 |
26 | private String GetUrl()
27 | {
28 | return m_url;
29 | }
30 |
31 | private void SetUrl(String url)
32 | {
33 | m_url = url;
34 | }
35 |
36 | private void SetAcsResponseParam(AcsResponse param)
37 | {
38 | m_acsResponseParam = param;
39 | }
40 |
41 | private void ReturnAcsResponse(String acsResponseString)
42 | {
43 | m_acsResponseParam.SetAcsResponseString(acsResponseString);
44 | }
45 |
46 | private String m_url;
47 | private AcsResponse m_acsResponseParam; // Ref to caller provided.
48 |
49 | private void BrowserForm_Load(object sender, EventArgs e)
50 | {
51 | this.Browser.Navigate(GetUrl());
52 | }
53 |
54 | private void WebBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
55 | {
56 | try
57 | {
58 | // Check if we are about to submit the SAML token returned by ACS.
59 | if (String.Compare(e.Url.AbsoluteUri, GetUrl(), true) == 0)
60 | {
61 | // Extract ACS response.
62 | if (this.Browser.Document.All["wresult"] != null)
63 | {
64 | // Cancel the request so that the POST doesn't actually happen.
65 | e.Cancel = true;
66 |
67 | try
68 | {
69 | String acsResponse;
70 |
71 | //
72 | // The ACS response that needs to be posted back has to be in a very
73 | // specific format.
74 | //
75 |
76 | dynamic wa = this.Browser.Document.All["wa"].DomElement;
77 | String waString = System.Web.HttpUtility.HtmlDecode(wa.value);
78 | #if false
79 | Console.WriteLine("wa={0}", waString);
80 | #endif
81 |
82 | dynamic wresult = this.Browser.Document.All["wresult"].DomElement;
83 | String wresultString = System.Web.HttpUtility.HtmlDecode(wresult.value);
84 | wresultString = wresultString.Replace("&", "&");
85 | #if false
86 | Console.WriteLine("wresult={0}", wresultString);
87 | #endif
88 |
89 | dynamic wctx = this.Browser.Document.All["wctx"].DomElement;
90 | String wctxString = System.Web.HttpUtility.HtmlDecode(wctx.value);
91 | #if false
92 | Console.WriteLine("wctx={0}", wctxString);
93 | #endif
94 |
95 | acsResponse = "wa=" + System.Web.HttpUtility.UrlEncode(waString, Encoding.ASCII) + "&" +
96 | "wresult=" + System.Web.HttpUtility.UrlEncode(wresultString, Encoding.ASCII) + "&" +
97 | "wctx=" + System.Web.HttpUtility.UrlEncode(wctxString, Encoding.ASCII);
98 |
99 | #if false
100 | Console.WriteLine("URL encoded ACS response:");
101 | Console.WriteLine(acsResponse);
102 | #endif
103 |
104 | ReturnAcsResponse(acsResponse);
105 | }
106 | catch (Exception exception)
107 | {
108 | Console.WriteLine(exception.ToString());
109 | }
110 |
111 | // Close the browser form.
112 | this.Dispose();
113 | }
114 | }
115 | }
116 | catch (Exception )
117 | {
118 |
119 | }
120 | }
121 |
122 | private void BrowserForm_Closing(object sender, CancelEventArgs e)
123 | {
124 | //this.navigationCanceled = true;
125 | }
126 |
127 | }
128 |
129 | public class AcsResponse
130 | {
131 | public AcsResponse()
132 | {
133 | m_acsResponseString = String.Empty;
134 | }
135 |
136 | public void SetAcsResponseString(String acsResponseString)
137 | {
138 | m_acsResponseString = acsResponseString;
139 | }
140 |
141 | public String GetAcsResponseString()
142 | {
143 | return m_acsResponseString;
144 | }
145 |
146 | private String m_acsResponseString;
147 | }
148 |
149 | }
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/BrowserForm.designer.cs:
--------------------------------------------------------------------------------
1 | namespace ODataConsoleApplication
2 | {
3 | partial class BrowserForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.Browser = new System.Windows.Forms.WebBrowser();
32 | this.SuspendLayout();
33 | //
34 | // Browser
35 | //
36 | this.Browser.Dock = System.Windows.Forms.DockStyle.Fill;
37 | this.Browser.Location = new System.Drawing.Point(0, 0);
38 | this.Browser.MinimumSize = new System.Drawing.Size(20, 20);
39 | this.Browser.Name = "Browser";
40 | //this.Browser.ScrollBarsEnabled = false;
41 | this.Browser.Size = new System.Drawing.Size(903, 403);
42 | this.Browser.TabIndex = 0;
43 | this.Browser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.WebBrowser_Navigating);
44 | //
45 | // BrowserForm
46 | //
47 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
48 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
49 | this.ClientSize = new System.Drawing.Size(903, 403);
50 | this.Controls.Add(this.Browser);
51 | this.Name = "BrowserForm";
52 | this.Text = "BrowserForm";
53 | this.Load += new System.EventHandler(this.BrowserForm_Load);
54 | this.Closing += new System.ComponentModel.CancelEventHandler(BrowserForm_Closing);
55 | this.ResumeLayout(false);
56 | }
57 |
58 | #endregion
59 |
60 | private System.Windows.Forms.WebBrowser Browser;
61 | }
62 | }
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/BrowserForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/CloudEnvironment.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
217 |
218 |
219 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/ODataConsoleApplication.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {621892ED-222F-4FA6-BCD8-61C82CEAFCA3}
8 | Exe
9 | Properties
10 | ODataConsoleApplication
11 | ODataConsoleApplication
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 |
37 |
38 |
39 | False
40 | ..\..\..\..\..\..\Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5\Microsoft.IdentityModel.dll
41 |
42 |
43 | .\Microsoft.OData.Client.dll
44 |
45 |
46 | .\Microsoft.OData.Core.dll
47 |
48 |
49 | .\Microsoft.OData.Edm.dll
50 |
51 |
52 | .\Microsoft.Spatial.dll
53 |
54 |
55 | .\MS.Dynamics.TestTools.CloudCommonTestUtilities.dll
56 |
57 |
58 | .\MS.Dynamics.TestTools.Common.dll
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | True
78 | True
79 | ODataProxies.tt
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | TextTemplatingFileGenerator
88 | ODataProxies.cs
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
109 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/ODataConsoleApplication.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODataConsoleApplication", "ODataConsoleApplication.csproj", "{621892ED-222F-4FA6-BCD8-61C82CEAFCA3}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {621892ED-222F-4FA6-BCD8-61C82CEAFCA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {621892ED-222F-4FA6-BCD8-61C82CEAFCA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {621892ED-222F-4FA6-BCD8-61C82CEAFCA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {621892ED-222F-4FA6-BCD8-61C82CEAFCA3}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/ODataProxies.odata.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | //using System.Data.Services.Client;
7 | //using ODataConsoleClient;
8 | using System.IO;
9 | using MS.Dynamics.TestTools.CloudCommonTestUtilities.Authentication;
10 | using Microsoft.OData.Client;
11 | using System.Net;
12 |
13 |
14 | namespace ODataConsoleClient
15 | {
16 | class Program
17 | {
18 |
19 | private static EventHandler _ODataResource_SendingRequest = new EventHandler(OnSendingRequest);
20 |
21 | ///
22 | /// Does all needed initialization to the context object
23 | ///
24 | /// the data context object to initialize
25 | public static void InitializeContextObject(DataServiceContext contextObject)
26 | {
27 | // Make sure it is not null
28 | if (contextObject == null)
29 | {
30 | throw new ArgumentNullException("contextObject");
31 | }
32 |
33 | // Register to the send request event in order to add the request header
34 | contextObject.SendingRequest2 += new EventHandler(_ODataResource_SendingRequest);
35 | }
36 |
37 |
38 | ///
39 | /// Adds to the request the cookie header for the security token
40 | ///
41 | /// the sender of the event
42 | /// the args for adding the cookie to
43 | public static void OnSendingRequest(object sender, SendingRequest2EventArgs e)
44 | {
45 | // Add the cookie in the commonUtil to the cookie header to authenticate call to service
46 | e.RequestMessage.SetHeader(HttpRequestHeader.Cookie.ToString(), AuthenticationUtils.GetCookie(AuthenticatorFactory.AdminAuthenticator));
47 | }
48 |
49 |
50 | public static Resources context;
51 |
52 | [STAThread]
53 | static void Main(string[] args)
54 | {
55 | string ODataServiceEndpoint = "https://usncax1aos.cloud.onebox.dynamics.com/data";
56 |
57 | Uri dynODataURI = new Uri(ODataServiceEndpoint, UriKind.Absolute);
58 | //Creates a DataServiceContext class which encapsulates operations that are supported by the OData endpoint
59 | context = new Resources(dynODataURI);
60 |
61 | //Authenticate the user
62 | //AuthenticationHelper.PerformAuthentication(context);
63 | Program.InitializeContextObject(context);
64 |
65 | CreateExchange();
66 |
67 | Console.WriteLine("-------------------------------------------------------------------");
68 | Console.WriteLine("Query all the customers in Fleet Management. Enter to start ...");
69 | Console.WriteLine("-------------------------------------------------------------------");
70 | Console.ReadLine();
71 |
72 | GetAllCustomers();
73 |
74 | Console.WriteLine();
75 | Console.WriteLine("-------------------------------------");
76 | Console.WriteLine("Create a new customer. Enter to start");
77 | Console.WriteLine("-------------------------------------");
78 | Console.ReadLine();
79 |
80 |
81 | Customer newCustomer = CreateCustomer();
82 |
83 |
84 | Console.WriteLine();
85 | Console.WriteLine("--------------------------------------------------------------------");
86 | Console.WriteLine("Create a new reservation for the customer. Enter to start ...");
87 | Console.WriteLine("--------------------------------------------------------------------");
88 | Console.ReadLine();
89 |
90 | CreateReservation(newCustomer);
91 |
92 |
93 | Console.ForegroundColor = ConsoleColor.White;
94 | Console.BackgroundColor = ConsoleColor.Black;
95 |
96 | Console.WriteLine();
97 |
98 | Console.WriteLine("***************************************************");
99 | Console.WriteLine("* *");
100 | Console.WriteLine("You have successfully completed, \t\t\n 1. Creating a new customer \t\t\t\n 2. Creating a new reservation for that customer. \n " +
101 | "Please refer back to Hands on Lab documentation to continue \n Press Enter to close this application \t");
102 | Console.WriteLine("* *");
103 | Console.WriteLine("***************************************************");
104 |
105 | Console.ReadLine();
106 |
107 | }
108 |
109 | ///
110 | /// This method issues a query URI to retrieve all the Customers from the Customer OData Entity
111 | ///
112 | private static void GetAllCustomers()
113 | {
114 | //Using the DataServiceContext class, we can simply perform a LINQ query to retrieve all Customers from the Customer entity.
115 | //This internally will issue web request by using the URI that represents OData protocol
116 | var query = from customer in context.Customers
117 | select customer;
118 |
119 |
120 | Console.ForegroundColor = ConsoleColor.Cyan;
121 | //Display the http request Uri that was sent to fetch all customers
122 | Console.WriteLine("Request Uri: " + query.ToString());
123 | Console.ForegroundColor = ConsoleColor.White;
124 |
125 | Console.WriteLine();
126 |
127 | //After retrieving all the customers, iterate through the collection and print each one.
128 | foreach (Customer c in query)
129 | {
130 | Console.WriteLine("Customer.RecId: " + c.RecId);
131 | Console.WriteLine("First Name: " + c.FirstName);
132 | Console.WriteLine("Last Name: " + c.LastName);
133 |
134 | Console.WriteLine("++++++++");
135 | }
136 | }
137 |
138 |
139 | ///
140 | /// This method prompts the user for first name and last name and then uses that to create a new customer by calling the Customer OData entity
141 | ///
142 | ///
143 | private static Customer CreateCustomer()
144 | {
145 |
146 | Console.WriteLine("Enter First Name, and then press Enter");
147 | string firstName = Console.ReadLine();
148 |
149 | Console.WriteLine("Enter Last Name, and then press Enter ");
150 | string lastName = Console.ReadLine();
151 |
152 | //Create the Customer object with the first and last names provided by the user
153 | Customer newCustomer = new Customer()
154 | {
155 | FirstName = firstName,
156 | LastName = lastName,
157 | CellPhone = "0123456789",
158 | Email = "test@contoso.com"
159 | };
160 |
161 | //Add the new customer object to the DataServiceContext object
162 | context.AddToCustomers(newCustomer);
163 |
164 | //Save the DataServiceContext object and an internally a POST call is made to the OData Customer entity.
165 | //Record is created in Rainier Database
166 | OperationResponse response = context.SaveChanges().First();
167 |
168 | Console.ForegroundColor = ConsoleColor.Cyan;
169 | if (response.Error == null)
170 | {
171 | Console.WriteLine("New customer created: ");
172 | //Display the URI of the new customer
173 | Console.WriteLine(response.Headers["Location"]);
174 | }
175 | Console.ForegroundColor = ConsoleColor.White;
176 |
177 | return newCustomer ;
178 | }
179 |
180 | private static SVC_ODataPersonView_DE CreateExchange()
181 | {
182 | DataServiceCollection svcOdata = new DataServiceCollection(context);
183 |
184 | var newExchange = new SVC_ODataPersonView_DE();
185 | svcOdata.Add(newExchange);
186 |
187 | newExchange.Name = "foo bar";
188 | newExchange.Email = "kuntal-test";
189 |
190 | context.SaveChanges(SaveChangesOptions.PostOnlySetProperties);
191 |
192 | //context.SaveChanges();
193 |
194 | return newExchange;
195 |
196 | }
197 |
198 | ///
199 | /// This method creates a new reservation record for the customer, created by the CreateCustomer method.
200 | ///
201 | ///
202 | ///
203 | private static Reservation CreateReservation(Customer customer)
204 | {
205 | Random rnd = new Random ();
206 |
207 | //Create a new Reservation object with the details for new customer.
208 | Reservation reservation = new Reservation()
209 | {
210 | Customer = customer,
211 | PickupDate = DateTime.Today,
212 | ReturnDate = DateTime.Today.AddDays (5.0),
213 | State =0, //Limitation of OData, no client-side Enum support
214 | ReservationId = "OData_" + rnd.Next (500).ToString ()
215 | };
216 |
217 | //Query the vehicle Odata Entity to retrieve the first vehicle from the list
218 | var vehicle = (from v in context.Vehicles
219 | select v).First();
220 |
221 |
222 | // Set up the relationship between (a) reservation and vehicle and (b) reservation and customer.
223 |
224 | //Add a link to the customer from the reservation
225 | reservation.Customer = customer;
226 | reservation.CustomerId = customer.RecId;
227 | customer.Reservations.Add(reservation);
228 |
229 | context.AddToReservations(reservation);
230 | context.AddLink(customer, "Reservations", reservation);
231 |
232 | //add link to the vehicle from the reservation
233 | reservation.Vehicle = vehicle;
234 | reservation.VehicleId = vehicle.RecId;
235 | vehicle.Reservations.Add(reservation);
236 | context.SetLink(reservation, "Vehicle", vehicle);
237 |
238 | // Now that we have created a new reservation and set the required relationship with customer and vehicle,
239 | // we will save these changes. Internally, this will also
240 | // perform a POST to the Reservation OData Entity.
241 | OperationResponse response = context.SaveChanges().First();
242 |
243 | Console.ForegroundColor = ConsoleColor.Cyan;
244 | if (response.Error == null)
245 | {
246 | Console.WriteLine("New Reservation created");
247 | //Display the URI of the newly created reservation
248 | Console.WriteLine(response.Headers["Location"]);
249 | }
250 | Console.ForegroundColor = ConsoleColor.White;
251 |
252 | return reservation;
253 |
254 | }
255 |
256 |
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/FMLab/ODataConsoleApplication/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/AuthenticationHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.ServiceModel;
6 | using Microsoft.IdentityModel.Protocols.WSTrust;
7 | using System.IdentityModel.Tokens;
8 | using WindowsForms = System.Windows.Forms;
9 | using Microsoft.IdentityModel.Tokens.Saml2;
10 | using Microsoft.IdentityModel.Tokens.Saml11;
11 | using System.IO;
12 | using System.Xml;
13 | using System.Net;
14 | using System.Net.Security;
15 | using System.Security.Cryptography.X509Certificates;
16 | using System.Globalization;
17 | using System.Configuration;
18 | using System.Diagnostics;
19 | using ODataClient.Microsoft.Dynamics.DataEntities;
20 | using System.Data.Services.Client;
21 | using Microsoft.OData.Client;
22 |
23 | namespace Odata4ConsoleApplication
24 | {
25 | internal class AuthenticationHelper
26 | {
27 | //const string aosUrl = "https://usnconeboxax1aos.cloud.onebox.dynamics.com/";
28 | private static String cookies;
29 |
30 | internal static string PerformAuthentication(Resources context, string aosUrl)
31 | {
32 |
33 | AcsResponse param = new AcsResponse();
34 | BrowserForm browserForm = new BrowserForm(aosUrl, param);
35 | WindowsForms.Application.Run(browserForm);
36 |
37 | HttpWebRequest httpRequest;
38 | HttpWebResponse httpResponse;
39 | CookieContainer cookieContainer = new CookieContainer();
40 |
41 | httpRequest = (HttpWebRequest)WebRequest.Create(aosUrl);
42 | httpRequest.Method = "POST";
43 | httpRequest.ContentType = "application/x-www-form-urlencoded";
44 |
45 | httpRequest.AllowAutoRedirect = true;
46 | httpRequest.CookieContainer = cookieContainer;
47 |
48 | StreamWriter writer = new StreamWriter(httpRequest.GetRequestStream(), Encoding.ASCII);
49 | writer.Write(param.GetAcsResponseString());
50 | writer.Flush();
51 | writer.Close();
52 |
53 | httpResponse = (HttpWebResponse)httpRequest.GetResponse();
54 | httpResponse.Close();
55 |
56 | StringBuilder retval = new StringBuilder();
57 |
58 | CookieCollection cookiesCollection = cookieContainer.GetCookies(new Uri(aosUrl));
59 |
60 | if (cookiesCollection.Count > 0)
61 | {
62 | foreach (Cookie c in cookiesCollection)
63 | {
64 | retval.AppendFormat("{0}={1}; ", c.Name, c.Value);
65 | }
66 |
67 | //Remove the trailing "; "
68 | retval.Remove(retval.Length - 2, 2);
69 | }
70 |
71 | cookies = retval.ToString();
72 |
73 | context.SendingRequest2 += new EventHandler(OnSendingRequest);
74 |
75 | return cookies;
76 | }
77 |
78 | public static void OnSendingRequest(object sender, SendingRequest2EventArgs e)
79 | {
80 | // Add the cookie to the cookie header to all requests
81 | e.RequestMessage.SetHeader(HttpRequestHeader.Cookie.ToString(), cookies);
82 | }
83 |
84 | }
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/BrowserForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using System.Xml;
10 | using System.Web;
11 | using System.Diagnostics;
12 | using System.Globalization;
13 | using System.Text.RegularExpressions;
14 |
15 | namespace Odata4ConsoleApplication
16 | {
17 | public partial class BrowserForm : Form
18 | {
19 | public BrowserForm(String url, AcsResponse param)
20 | {
21 | SetUrl(url);
22 | SetAcsResponseParam(param);
23 | InitializeComponent();
24 | }
25 |
26 | private String GetUrl()
27 | {
28 | return m_url;
29 | }
30 |
31 | private void SetUrl(String url)
32 | {
33 | m_url = url;
34 | }
35 |
36 | private void SetAcsResponseParam(AcsResponse param)
37 | {
38 | m_acsResponseParam = param;
39 | }
40 |
41 | private void ReturnAcsResponse(String acsResponseString)
42 | {
43 | m_acsResponseParam.SetAcsResponseString(acsResponseString);
44 | }
45 |
46 | private String m_url;
47 | private AcsResponse m_acsResponseParam; // Ref to caller provided.
48 |
49 | private void BrowserForm_Load(object sender, EventArgs e)
50 | {
51 | this.Browser.Navigate(GetUrl());
52 | }
53 |
54 | private void WebBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
55 | {
56 | try
57 | {
58 | // Check if we are about to submit the SAML token returned by ACS.
59 | if (String.Compare(e.Url.AbsoluteUri, GetUrl(), true) == 0)
60 | {
61 | // Extract ACS response.
62 | if (this.Browser.Document != null && this.Browser.Document.All["wresult"] != null)
63 | {
64 | // Cancel the request so that the POST doesn't actually happen.
65 | e.Cancel = true;
66 |
67 | try
68 | {
69 | String acsResponse;
70 |
71 | //
72 | // The ACS response that needs to be posted back has to be in a very
73 | // specific format.
74 | //
75 |
76 | dynamic wa = this.Browser.Document.All["wa"].DomElement;
77 | String waString = System.Web.HttpUtility.HtmlDecode(wa.value);
78 | #if false
79 | Console.WriteLine("wa={0}", waString);
80 | #endif
81 |
82 | dynamic wresult = this.Browser.Document.All["wresult"].DomElement;
83 | String wresultString = System.Web.HttpUtility.HtmlDecode(wresult.value);
84 | wresultString = wresultString.Replace("&", "&");
85 | #if false
86 | Console.WriteLine("wresult={0}", wresultString);
87 | #endif
88 |
89 | dynamic wctx = this.Browser.Document.All["wctx"].DomElement;
90 | String wctxString = System.Web.HttpUtility.HtmlDecode(wctx.value);
91 | #if false
92 | Console.WriteLine("wctx={0}", wctxString);
93 | #endif
94 |
95 | acsResponse = "wa=" + System.Web.HttpUtility.UrlEncode(waString, Encoding.ASCII) + "&" +
96 | "wresult=" + System.Web.HttpUtility.UrlEncode(wresultString, Encoding.ASCII) + "&" +
97 | "wctx=" + System.Web.HttpUtility.UrlEncode(wctxString, Encoding.ASCII);
98 |
99 | #if false
100 | Console.WriteLine("URL encoded ACS response:");
101 | Console.WriteLine(acsResponse);
102 | #endif
103 |
104 | ReturnAcsResponse(acsResponse);
105 | }
106 | catch (Exception exception)
107 | {
108 | Console.WriteLine(exception.ToString());
109 | }
110 |
111 | // Close the browser form.
112 | this.Dispose();
113 | }
114 | }
115 | }
116 | catch (Exception )
117 | {
118 |
119 | }
120 | }
121 |
122 | private void BrowserForm_Closing(object sender, CancelEventArgs e)
123 | {
124 | //this.navigationCanceled = true;
125 | }
126 |
127 | }
128 |
129 | public class AcsResponse
130 | {
131 | public AcsResponse()
132 | {
133 | m_acsResponseString = String.Empty;
134 | }
135 |
136 | public void SetAcsResponseString(String acsResponseString)
137 | {
138 | m_acsResponseString = acsResponseString;
139 | }
140 |
141 | public String GetAcsResponseString()
142 | {
143 | return m_acsResponseString;
144 | }
145 |
146 | private String m_acsResponseString;
147 | }
148 |
149 | }
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/BrowserForm.designer.cs:
--------------------------------------------------------------------------------
1 | namespace Odata4ConsoleApplication
2 | {
3 | partial class BrowserForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.Browser = new System.Windows.Forms.WebBrowser();
32 | this.SuspendLayout();
33 | //
34 | // Browser
35 | //
36 | this.Browser.Dock = System.Windows.Forms.DockStyle.Fill;
37 | this.Browser.Location = new System.Drawing.Point(0, 0);
38 | this.Browser.MinimumSize = new System.Drawing.Size(20, 20);
39 | this.Browser.Name = "Browser";
40 | //this.Browser.ScrollBarsEnabled = false;
41 | this.Browser.Size = new System.Drawing.Size(903, 403);
42 | this.Browser.TabIndex = 0;
43 | this.Browser.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.WebBrowser_Navigating);
44 | //
45 | // BrowserForm
46 | //
47 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
48 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
49 | this.ClientSize = new System.Drawing.Size(903, 403);
50 | this.Controls.Add(this.Browser);
51 | this.Name = "BrowserForm";
52 | this.Text = "BrowserForm";
53 | this.Load += new System.EventHandler(this.BrowserForm_Load);
54 | this.Closing += new System.ComponentModel.CancelEventHandler(BrowserForm_Closing);
55 | this.ResumeLayout(false);
56 | }
57 |
58 | #endregion
59 |
60 | private System.Windows.Forms.WebBrowser Browser;
61 | }
62 | }
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/BrowserForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/ODataProxyGenerator.tt:
--------------------------------------------------------------------------------
1 | <#@ include file="ODataProxyGenerator.ttinclude" #>
2 | <#+
3 | public static class Configuration
4 | {
5 | // The URI of the metadata document. The value must be set to a valid service document URI or a local file path
6 | // eg : "http://services.odata.org/V4/OData/OData.svc/", "File:///C:/Odata.edmx", or @"C:\Odata.edmx"
7 | // ### Notice ### If the OData service requires authentication for accessing the metadata document, the value of
8 | // MetadataDocumentUri has to be set to a local file path, or the client code generation process will fail.
9 |
10 | public const string MetadataDocumentUri = "/data/";
11 |
12 | // The use of DataServiceCollection enables entity and property tracking. The value must be set to true or false.
13 | public const bool UseDataServiceCollection = true;
14 |
15 | // The namespace of the client code generated. It replaces the original namspace in the metadata document,
16 | // unless the model has several namespaces.
17 | public const string NamespacePrefix = "ODataClient";
18 |
19 | // The target language of the generated client code. The value must be set to "CSharp" or "VB".
20 | public const string TargetLanguage = "CSharp";
21 |
22 | // This flag indicates whether to enable naming alias. The value must be set to true or false.
23 | public const bool EnableNamingAlias = true;
24 |
25 | // This flag indicates whether to ignore unexpected elements and attributes in the metadata document and generate
26 | // the client code if any. The value must be set to true or false.
27 | public const bool IgnoreUnexpectedElementsAndAttributes = true;
28 | }
29 |
30 | public static class Customization
31 | {
32 | ///
33 | /// Changes the text to use upper camel case, which upper case for the first character.
34 | ///
35 | /// Text to convert.
36 | /// The converted text in upper camel case
37 | internal static string CustomizeNaming(string text)
38 | {
39 | if (string.IsNullOrEmpty(text))
40 | {
41 | return text;
42 | }
43 |
44 | if (text.Length == 1)
45 | {
46 | return Char.ToUpperInvariant(text[0]).ToString(CultureInfo.InvariantCulture);
47 | }
48 |
49 | return Char.ToUpperInvariant(text[0]) + text.Substring(1);
50 | }
51 |
52 | ///
53 | /// Changes the namespace to use upper camel case, which upper case for the first character of all segments.
54 | ///
55 | /// Namespace to convert.
56 | /// The converted namespace in upper camel case
57 | internal static string CustomizeNamespace(string fullNamespace)
58 | {
59 | if (string.IsNullOrEmpty(fullNamespace))
60 | {
61 | return fullNamespace;
62 | }
63 |
64 | string[] segs = fullNamespace.Split('.');
65 | string upperNamespace = string.Empty;
66 | int n = segs.Length;
67 | for (int i = 0; i < n; ++i)
68 | {
69 | upperNamespace += Customization.CustomizeNaming(segs[i]);
70 | upperNamespace += (i == n - 1 ? string.Empty : ".");
71 | }
72 |
73 | return upperNamespace;
74 | }
75 | }
76 | #>
77 |
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/Odata4ConsoleApplication.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {86E584DD-9A75-4DA3-973E-B5AF5CEE23A9}
8 | Exe
9 | Properties
10 | Odata4ConsoleApplication
11 | Odata4ConsoleApplication
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | False
37 | .\Microsoft.IdentityModel.dll
38 |
39 |
40 | .\Microsoft.OData.Client.dll
41 |
42 |
43 | .\Microsoft.OData.Core.dll
44 |
45 |
46 | .\Microsoft.OData.Edm.dll
47 |
48 |
49 | .\Microsoft.Spatial.dll
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Form
70 |
71 |
72 |
73 | True
74 | True
75 | ODataProxyGenerator.tt
76 |
77 |
78 |
79 |
80 |
81 |
82 | TextTemplatingFileGenerator
83 | ODataProxyGenerator.cs
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
104 |
--------------------------------------------------------------------------------
/FMLab/Odata4ConsoleApplication/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using ODataClient.Microsoft.Dynamics.DataEntities;
7 | using Microsoft.OData.Client;
8 | using System.Net.Http;
9 |
10 |
11 | namespace Odata4ConsoleApplication
12 | {
13 | class Program
14 | {
15 |
16 | public static Resources context;
17 |
18 | [STAThread]
19 | static void Main(string[] args)
20 | {
21 | //the following BaseUri needs to be updated to your org
22 | string dynamicsBaseUri = "https://usnconeboxax1aos.cloud.onebox.dynamics.com/";
23 | string ODataServiceEndpoint = dynamicsBaseUri + "data";
24 |
25 | Uri dynODataURI = new Uri(ODataServiceEndpoint, UriKind.Absolute);
26 |
27 | //Creates a DataServiceContext class which encapsulates operations that are supported by the OData endpoint
28 | context = new Resources(dynODataURI);
29 |
30 | //Authenticate the user
31 | AuthenticationHelper.PerformAuthentication(context,dynamicsBaseUri);
32 |
33 | Console.WriteLine("-------------------------------------------------------------------");
34 | Console.WriteLine("Query all the customers in Fleet Management. Enter to start ...");
35 | Console.WriteLine("-------------------------------------------------------------------");
36 | Console.ReadLine();
37 |
38 | GetAllCustomers();
39 |
40 | Console.WriteLine();
41 | Console.WriteLine("-------------------------------------");
42 | Console.WriteLine("Create a new customer. Enter to start");
43 | Console.WriteLine("-------------------------------------");
44 | Console.ReadLine();
45 |
46 |
47 | FleetCustomer newCustomer = CreateCustomer();
48 |
49 | Console.WriteLine();
50 | Console.WriteLine("--------------------------------------------------------------------");
51 | Console.WriteLine("Create a new reservation for the customer. Enter to start ...");
52 | Console.WriteLine("--------------------------------------------------------------------");
53 | Console.ReadLine();
54 |
55 | FleetRental newRental = CreateReservation(newCustomer);
56 |
57 | Console.WriteLine();
58 | Console.WriteLine("--------------------------------------------------------------------");
59 | Console.WriteLine("Call action on the reservation ...");
60 | Console.WriteLine("--------------------------------------------------------------------");
61 | Console.ReadLine();
62 |
63 | UriBuilder buildUri = new UriBuilder(ODataServiceEndpoint);
64 | buildUri.Path = String.Format("data/FleetRentals('{0}')/Microsoft.Dynamics.DataEntities.ReturnRental", newRental.RentalId);
65 |
66 | //following code invokes the action by sending an HTTPPost request for the buildUri
67 | var returnValue = context.Execute(new Uri(buildUri.ToString()), "POST", true);
68 |
69 | Console.ForegroundColor = ConsoleColor.Cyan;
70 | Console.WriteLine("Invoked ReturnRental action, response is: \n" + returnValue.Single());
71 |
72 | Console.ForegroundColor = ConsoleColor.White;
73 | Console.BackgroundColor = ConsoleColor.Black;
74 |
75 | Console.WriteLine();
76 |
77 | Console.WriteLine("***************************************************");
78 | Console.WriteLine("* *");
79 | Console.WriteLine("You have successfully completed, \t\t\n 1. Creating a new customer \t\t\t\n 2. Creating a new reservation for that customer. \n " +
80 | "Please refer back to Hands on Lab documentation to continue \n Press Enter to close this application \t");
81 | Console.WriteLine("* *");
82 | Console.WriteLine("***************************************************");
83 |
84 | Console.ReadLine();
85 |
86 | }
87 |
88 | ///
89 | /// This method issues a query URI to retrieve all the Customers from the Customer OData Entity
90 | ///
91 | private static void GetAllCustomers()
92 | {
93 | //Using the DataServiceContext class, we can simply perform a LINQ query to retrieve all Customers from the Customer entity.
94 | //This internally will issue web request by using the URI that represents OData protocol
95 | //get all customers
96 | var query = from customer in context.FleetCustomers
97 | select customer;
98 |
99 | Console.ForegroundColor = ConsoleColor.Cyan;
100 | //Display the http request Uri that was sent to fetch all customers
101 | Console.WriteLine("Request Uri: " + query.ToString());
102 | Console.ForegroundColor = ConsoleColor.White;
103 |
104 | Console.WriteLine();
105 |
106 | //After retrieving all the customers, iterate through the collection and print each one.
107 | foreach (FleetCustomer c in query)
108 | {
109 | Console.WriteLine("Customer.Driver License: " + c.DriverLicense);
110 | Console.WriteLine("First Name: " + c.FirstName);
111 | Console.WriteLine("Last Name: " + c.LastName);
112 |
113 | Console.WriteLine("++++++++");
114 | }
115 | }
116 |
117 | ///
118 | /// This method prompts the user for first name and last name and then uses that to create a new customer by calling the Customer OData entity
119 | ///
120 | ///
121 | private static FleetCustomer CreateCustomer()
122 | {
123 |
124 | Console.WriteLine("Enter First Name, and then press Enter");
125 | string firstName = Console.ReadLine();
126 |
127 | Console.WriteLine("Enter Last Name, and then press Enter ");
128 | string lastName = Console.ReadLine();
129 |
130 | Random rnd = new Random();
131 |
132 | //Create the Customer object with the first and last names provided by the user
133 | FleetCustomer newCustomer = new FleetCustomer()
134 | {
135 | FirstName = firstName,
136 | LastName = lastName,
137 | DriverLicense = "B923-2381-" + rnd.Next(1000,7000).ToString(),
138 | CellPhone = "0123456789",
139 | Email = "test@contoso.com",
140 | };
141 |
142 | //Add the new customer object to the DataServiceContext object
143 | context.AddToFleetCustomers(newCustomer);
144 |
145 | //Save the DataServiceContext object and an internally a POST call is made to the OData Customer entity.
146 | //Record is created in Rainier Database
147 | Microsoft.OData.Client.DataServiceResponse response = null;
148 | try
149 | {
150 | response = context.SaveChanges();
151 | }
152 | catch (DataServiceRequestException e)
153 | {
154 | Console.WriteLine("Error occured while saving. Error Details: " + e.InnerException.Message);
155 | }
156 |
157 | //the following code retrieves the location header which represents the newly created entity
158 | foreach (ChangeOperationResponse r in response)
159 | {
160 | if (r.Headers.ContainsKey("Location"))
161 | {
162 | Console.ForegroundColor = ConsoleColor.Cyan;
163 | Console.WriteLine("New customer created: ");
164 | Console.WriteLine(r.Headers["Location"]);
165 | }
166 | }
167 |
168 | Console.ForegroundColor = ConsoleColor.White;
169 |
170 | return newCustomer;
171 | }
172 |
173 |
174 | ///
175 | /// This method creates a new reservation record for the customer, created by the CreateCustomer method.
176 | ///
177 | ///
178 | ///
179 | private static FleetRental CreateReservation(FleetCustomer customer)
180 | {
181 | Random rnd = new Random();
182 |
183 | DataServiceCollection reservations = new DataServiceCollection(context);
184 |
185 | FleetRental reservation = new FleetRental();
186 |
187 | reservations.Add(reservation);
188 | //Create a new Reservation object with the details for new customer.
189 |
190 |
191 | reservation.CustomerFirstName = customer.FirstName;
192 | reservation.CustomerLastName = customer.LastName;
193 | reservation.CustomerDriverLicense = customer.DriverLicense;
194 | reservation.State = 0; //Limitation of OData, no client-side Enum support
195 | reservation.RentalId = "OData_" + rnd.Next(500).ToString();
196 | reservation.Comments = "New customer";
197 | reservation.VehicleId = "Adatum_Four_2";
198 | reservation.VehicleVIN = "WAUXL58E15A104563";
199 | reservation.EndDate = DateTime.Today.AddDays (5);
200 | reservation.StartDate = DateTime.Today;
201 |
202 |
203 | Microsoft.OData.Client.DataServiceResponse response = null;
204 | try
205 | {
206 | response = context.SaveChanges(SaveChangesOptions.PostOnlySetProperties);
207 | }
208 | catch (DataServiceRequestException e)
209 | {
210 | Console.WriteLine("Error occured while saving. Error Details: " + e.InnerException.Message);
211 | }
212 |
213 |
214 | //the following code retrieves the location header which represents the newly created entity
215 | Console.ForegroundColor = ConsoleColor.Cyan;
216 | foreach (ChangeOperationResponse r in response)
217 | {
218 | if (r.Headers.ContainsKey("Location"))
219 | {
220 | Console.ForegroundColor = ConsoleColor.Cyan;
221 | Console.WriteLine("New reservation created: ");
222 | Console.WriteLine(r.Headers["Location"]);
223 | }
224 | }
225 | Console.ForegroundColor = ConsoleColor.White;
226 |
227 | return reservation;
228 |
229 | }
230 |
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/FMLab/TaskRecorderScreenshot/background.js:
--------------------------------------------------------------------------------
1 | chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
2 | if (request.name == 'screenshot') {
3 | chrome.tabs.captureVisibleTab(null, null, function(dataUrl) {
4 | sendResponse({ screenshotUrl: dataUrl });
5 | });
6 | }
7 | return true;
8 | });
9 |
--------------------------------------------------------------------------------
/FMLab/TaskRecorderScreenshot/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Dynamics 365 for Finance and Operations Task Recorder Screenshot Extension",
3 | "version": "1.0.0.2",
4 | "description": "Screenshot capture used for Dynamics 365 for Finance and Operations task recorder.",
5 | "background": {
6 | "scripts": ["background.js"]
7 | },
8 | "content_scripts": [
9 | {
10 | "matches": ["https://*.dynamics.com/*"],
11 | "js": ["screenshot.js"]
12 | }
13 | ],
14 | "permissions": [
15 | "tabs", ""
16 | ],
17 | "manifest_version": 2
18 | }
19 |
--------------------------------------------------------------------------------
/FMLab/TaskRecorderScreenshot/screenshot.js:
--------------------------------------------------------------------------------
1 | document.addEventListener("screenshot", function() {
2 | chrome.extension.sendMessage({name: 'screenshot'}, function(response) {
3 | var dataURL = response.screenshotUrl;
4 | var image = new Image();
5 |
6 | image.onload = function() {
7 | // Cut the task recorder pane from the screenshot.
8 | var ratio = window.devicePixelRatio;
9 | var canvas = document.createElement("canvas");
10 | var context = canvas.getContext('2d');
11 | canvas.width = window.innerWidth * ratio;
12 | canvas.height = window.innerHeight * ratio;
13 | var taskRecorderPaneWidth = document.getElementById('asidePane').clientWidth * ratio;
14 | context.drawImage(image, 0, 0, (canvas.width - taskRecorderPaneWidth), canvas.height, 0, 0, canvas.width, canvas.height);
15 | var croppedImage = canvas.toDataURL('image/png');
16 |
17 | var origin = window.location.protocol + "//" + window.location.host;
18 | window.postMessage(croppedImage, origin);
19 | };
20 | image.src = dataURL;
21 |
22 |
23 | });
24 | });
25 |
26 | var isInstalledNode = document.createElement('div');
27 | isInstalledNode.id = 'screenshotExtensionIsInstalled';
28 | document.body.appendChild(isInstalledNode);
--------------------------------------------------------------------------------
/FMLab/TestFiles/AxClass_FMUnitTestSample.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FMUnitTestSample
4 |
5 |
10 |
11 |
12 | setup
13 |
20 |
21 |
22 | testFMTotalsEngine
23 |
51 |
52 |
53 | testFMCarValidateField
54 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/FMLab/TestFiles/CodeCoverage.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 | .*Dynamics\.AX\.ApplicationPlatform\.*
10 | .*Dynamics\.AX\.FleetManagement\.*
11 |
12 |
13 |
14 | .*CPPUnitTestFramework.*
15 | .*AOSKernel.*
16 |
17 |
18 |
19 |
22 | 30000
23 | true
24 |
25 |
29 | true
30 |
31 |
37 | true
38 |
39 |
43 | true
44 |
45 |
48 |
49 | Network Service
50 | Everyone
51 |
52 |
53 |
56 |
57 | T:\Bin
58 | T:\modules\ApplicationSuite\bin
59 | T:\modules\ApplicationPlatform\bin
60 | T:\modules\ApplicationFoundation\bin
61 |
62 |
63 |
71 |
72 |
76 |
77 |
78 |
79 | .*test.*
80 |
81 |
82 |
83 |
88 |
89 |
90 |
91 | ^B77A5C561934E089$
92 | ^B03F5F7F11D50A3A$
93 | ^31BF3856AD364E35$
94 | ^89845DCD8080CC91$
95 | ^71E9BCE111E9429C$
96 | ^8F50407C4E9E73B6$
97 | ^E361AF139669C375$
98 |
99 |
100 |
101 |
105 |
106 |
107 |
108 | .*\\atlmfc\\.*
109 |
110 | .*\\vctools\\.*
111 |
112 | .*\\public\\sdk\\.*
113 | .*\\microsoft sdks\\.*
114 |
115 | .*\\vc\\include\\.*
116 |
117 |
118 |
119 |
124 |
125 |
126 | ^System.Diagnostics.DebuggerHiddenAttribute$
127 | ^System.Diagnostics.DebuggerNonUserCodeAttribute$
128 | ^System.Runtime.CompilerServices.CompilerGeneratedAttribute$
129 | ^System.CodeDom.Compiler.GeneratedCodeAttribute$
130 | ^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$
131 |
132 |
133 |
134 |
138 |
139 |
140 |
141 | ^std::.*
142 |
143 | ^ATL::.*
144 |
145 | .*::__GetTestMethodInfo.*
146 |
147 | .*__CxxPureMSILEntry.*
148 |
149 | ^Microsoft::VisualStudio::CppCodeCoverageFramework::.*
150 |
151 | ^Microsoft::VisualStudio::CppUnitTestFramework::.*
152 |
153 | .*::YOU_CAN_ONLY_DESIGNATE_ONE_.*
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/FMLab/TestFiles/Default.RunSettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | .\TestResults
7 |
8 |
10 | x64
11 |
12 |
13 |
14 |
15 |
16 |
17 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | initial
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/FMLab/json-ie.reg:
--------------------------------------------------------------------------------
1 | Windows Registry Editor Version 5.00
2 | ;
3 | ; Tell IE to open JSON documents in the browser.
4 | ; 25336920-03F9-11cf-8FD0-00AA00686F13 is the CLSID for the "Browse in place" .
5 | ;
6 |
7 | [HKEY_CLASSES_ROOT\MIME\Database\Content Type\application/json]
8 | "CLSID"="{25336920-03F9-11cf-8FD0-00AA00686F13}"
9 | "Encoding"=hex:08,00,00,00
10 |
11 | [HKEY_CLASSES_ROOT\MIME\Database\Content Type\text/json]
12 | "CLSID"="{25336920-03F9-11cf-8FD0-00AA00686F13}"
13 | "Encoding"=hex:08,00,00,00
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FMLab
2 | FMLab is the sample code you need for several of the Dynamics AX tutorials on http://ax.help.dynamics.com. These tutorials use a model named Fleet Management Tutorial.
3 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------