Modified the PAW-1 vm to also be the development VM with Visual studio image.  Added the Encrypted application.  Small updates to trainer guide (removal of preview statements).   Update Sentinel images/steps.
This commit is contained in:
Chris Givens 2020-01-28 15:17:56 -08:00
Родитель 9dcfba25c7
Коммит a6f44248b1
161 изменённых файлов: 67534 добавлений и 170 удалений

Просмотреть файл

@ -18,7 +18,7 @@ Microsoft may have patents, patent applications, trademarks, copyrights, or othe
The names of manufacturers, products, or URLs are provided for informational purposes only, and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement by Microsoft of the manufacturer or product. Links may be provided to third-party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein.
© 2019 Microsoft Corporation. All rights reserved.
© 2020 Microsoft Corporation. All rights reserved.
Microsoft and the trademarks listed at <https://www.microsoft.com/en-us/legal/intellectualproperty/Trademarks/Usage/General.aspx> are trademarks of the Microsoft group of companies. All other trademarks are the property of their respective owners.

Просмотреть файл

@ -507,11 +507,11 @@
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2016-Datacenter",
"publisher": "microsoftvisualstudio",
"offer": "visualstudio2019latest",
"sku": "vs-2019-comm-latest-ws2019",
"version": "latest"
},
},
"osDisk": {
"createOption": "fromImage",
"managedDisk": {

Просмотреть файл

@ -9,7 +9,7 @@ Before the hands-on lab setup guide
</div>
<div class="MCWHeader3">
October 2019
February 2020
</div>
@ -19,7 +19,7 @@ Microsoft may have patents, patent applications, trademarks, copyrights, or othe
The names of manufacturers, products, or URLs are provided for informational purposes only and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links may be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein.
© 2019 Microsoft Corporation. All rights reserved.
© 2020 Microsoft Corporation. All rights reserved.
Microsoft and the trademarks listed at <https://www.microsoft.com/en-us/legal/intellectualproperty/Trademarks/Usage/General.aspx> are trademarks of the Microsoft group of companies. All other trademarks are property of their respective owners.
@ -30,8 +30,10 @@ Microsoft and the trademarks listed at <https://www.microsoft.com/en-us/legal/in
- [Security baseline on Azure before the hands-on lab setup guide](#security-baseline-on-azure-before-the-hands-on-lab-setup-guide)
- [Requirements](#requirements)
- [Before the hands-on lab](#before-the-hands-on-lab)
- [Task 1: Download GitHub resources](#task-1-download-github-resources)
- [Task 2: Deploy resources to Azure](#task-2-deploy-resources-to-azure)
- [Task 1: Deploy resources to Azure](#task-1-deploy-resources-to-azure)
- [Task 2: Download Google Chrome](#task-2-download-google-chrome)
- [Task 3: Download SQL Server Management Studio](#task-3-download-sql-server-management-studio)
- [Task 4: Download GitHub resources](#task-4-download-github-resources)
<!-- /TOC -->
@ -43,7 +45,7 @@ Microsoft and the trademarks listed at <https://www.microsoft.com/en-us/legal/in
- Trial subscriptions will not work.
2. A machine with the following software installed:
2. A machine with the following software installed (a Virtual Machine is created via the ARM template with most of this):
- [Visual Studio 2019](https://visualstudio.microsoft.com/downloads/)
- [SQL Management Studio](https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms)
@ -57,19 +59,7 @@ Duration: 30 minutes
Synopsis: In this exercise, you will set up your environment for use in the rest of the hands-on lab. You should follow all the steps provided in the Before the Hands-on Lab section to prepare your environment *before* attending the workshop.
### Task 1: Download GitHub resources
1. Open a browser window to the cloud workshop GitHub repository (<https://github.com/microsoft/MCW-Security-baseline-on-Azure>).
2. Select **Clone or download**, then select **Download Zip**.
![Clone or download and Download ZIP are highlighted in this screenshot of the cloud workshop GitHub repository.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image3.png "Clone or Download Zip")
3. Extract the zip file to your local machine, be sure to keep note of where you have extracted the files. You should now see a set of folders:
![A set of extracted folders and files are visible in File Explorer: .vs, AzureTemplate, Database, Scripts, WebApp, README.md.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image4.png "Extract the zip file")
### Task 2: Deploy resources to Azure
### Task 1: Deploy resources to Azure
1. Open your Azure Portal.
@ -83,15 +73,15 @@ Synopsis: In this exercise, you will set up your environment for use in the rest
6. Select **Refresh** to see your new resource group displayed and select it. It may take a few minutes.
7. Select **Export template**, and then select **Deploy**.
7. Under **Settings**, select **Export template**, and then select **Deploy**.
![Automation script is highlighted under Settings on the left side of the Azure portal, and Deploy is highlighted on the top-right side.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image5.png "Select Deploy")
8. Select **Build your own template in the editor**.
9. In the extracted folder, open the **\\Hands-on lab\\Scripts\\template.json**.
9. Copy the contents of the [ARM template](https://raw.githubusercontent.com/microsoft/MCW-Security-baseline-on-Azure/master/Hands-on%20lab/Scripts/template.json) from the repo.
10. Copy and paste it into the window.
10. Paste the ARM template into the window.
11. Select **Save**, you will see the dialog with the input parameters. Fill out the form:
@ -117,7 +107,7 @@ Synopsis: In this exercise, you will set up your environment for use in the rest
![The above information is entered in the form, and I agree to the terms and conditions stated above and Purchase are selected and highlighted at the bottom.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image6.png "Fill out the form")
12. The deployment will take 15-30 minutes to complete. To view the progress, select the **Deployments** link, then select the **Microsoft.Template** deployment.
12. The deployment will take 20-40 minutes to complete. To view the progress, select the **Deployments** link, then select the **Microsoft.Template** deployment.
![Deployments is highlighted under Settings on the left side of the Azure portal, and Microsoft.Template is highlighted under Deployment Name on the right side.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image7.png "Select the Deployments link")
@ -128,10 +118,12 @@ Synopsis: In this exercise, you will set up your environment for use in the rest
- Three virtual networks (dbVNet, webVnet, mainVnet).
- Three network security groups.
- Three virtual machines with associated network resources (db-1, web-1, paw-1).
- Three lab supporting virtual machines with associated network resources (db-1, web-1, paw-1).
- IIS is installed on web-1 via a DSC script from the GitHub repository.
- paw-1 is used as a development machine for the labs to save on resources. A Paw workstation would not be used as a development machine in production with Visual Studio and SQL Management Studio. This was done to save on resource costs / setup complexity.
- SQL Azure Server with sample database.
@ -141,4 +133,30 @@ Synopsis: In this exercise, you will set up your environment for use in the rest
![Created items list This screenshot is a list of the items that were created, including the items listed above. ](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image8.png)
You should follow all steps provided *before* attending the hands-on lab.
### Task 2: Download Google Chrome
1. Login to the Virtual Machine created via the ARM template called **paw-1**
2. Open Internet Explorer and browse to <https://www.google.com/chrome/>.
3. Select **Download Chrome** on the webpage and follow the prompts.
### Task 3: Download SQL Server Management Studio
1. From the **paw-1** Virtual Machine, open Google Chrome and browse to <https://aka.ms/ssmsfullsetup>.
2. After the installer has completed downloading, run it and follow the prompts to install SQL Server Management Studio.
### Task 4: Download GitHub resources
1. Open a browser window to the cloud workshop GitHub repository (<https://github.com/microsoft/MCW-Security-baseline-on-Azure>).
2. Select **Clone or download**, then select **Download Zip**.
![Clone or download and Download ZIP are highlighted in this screenshot of the cloud workshop GitHub repository.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image3.png "Clone or Download Zip")
3. Extract the zip file to your local machine, be sure to keep note of where you have extracted the files (such as `c:\temp`). You should now see a set of folders:
![A set of extracted folders and files are visible in File Explorer: .vs, AzureTemplate, Database, Scripts, WebApp, README.md.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image4.png "Extract the zip file")
**NOTE** You should follow all steps provided *before* attending the hands-on lab.

Просмотреть файл

@ -9,7 +9,7 @@ Hands-on lab step-by-step
</div>
<div class="MCWHeader3">
October 2019
February 2020
</div>
Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
@ -18,7 +18,7 @@ Microsoft may have patents, patent applications, trademarks, copyrights, or othe
The names of manufacturers, products, or URLs are provided for informational purposes only, and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links may be provided to third-party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein.
© 2019 Microsoft Corporation. All rights reserved.
© 2020 Microsoft Corporation. All rights reserved.
Microsoft and the trademarks listed at <https://www.microsoft.com/en-us/legal/intellectualproperty/Trademarks/Usage/General.aspx> are trademarks of the Microsoft group of companies. All other trademarks are the property of their respective owners.
@ -46,9 +46,9 @@ Microsoft and the trademarks listed at <https://www.microsoft.com/en-us/legal/in
- [Task 4: Install or verify NuGet Package](#task-4-install-or-verify-nuget-package)
- [Task 5: Test the solution](#task-5-test-the-solution)
- [Exercise 4: Securing the network](#exercise-4-securing-the-network)
- [Task 1: Test network security group rules #1](#task-1-test-network-security-group-rules-1)
- [Task 1: Test network security group rules \#1](#task-1-test-network-security-group-rules-1)
- [Task 2: Configure network security groups](#task-2-configure-network-security-groups)
- [Task 3: Test network security group rules #2](#task-3-test-network-security-group-rules-2)
- [Task 3: Test network security group rules \#2](#task-3-test-network-security-group-rules-2)
- [Task 4: Install network watcher VM extension](#task-4-install-network-watcher-vm-extension)
- [Task 5: Setup network packet capture](#task-5-setup-network-packet-capture)
- [Task 6: Execute a port scan](#task-6-execute-a-port-scan)
@ -101,7 +101,7 @@ The solution begins by creating a jump machine. This jump machine is used to acc
2. A machine with the following software installed:
- Visual Studio 2017
- Visual Studio 2019
- SQL Management Studio
- Power BI Desktop
@ -117,7 +117,7 @@ Synopsis: In this exercise, attendees will secure a Privileged Access Workstatio
2. Select **Security Center,** then under **ADVANCED CLOUD DEFENSE** select **Just in time VM access**.
![Security Center is highlighted on the left side of the Azure portal, and Just in time VM access (Preview) is highlighted to the right.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image9.png)
![Security Center is highlighted on the left side of the Azure portal, and Just in time VM access is highlighted to the right.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image9.png)
> **Note**: Your subscription may not be set up with the **Standard** tier; if that is the case then do the following:
@ -140,9 +140,7 @@ Synopsis: In this exercise, attendees will secure a Privileged Access Workstatio
![In the configuration window, port settings are listed, and Save is highlighted above them.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image10.png "Select Save")
5. If you had to setup Just In Time, you should now see the states changed to **Resolved**.
> **Note**: It could take a couple minutes for this to revert to the resolved state.
5. After a few minutes, you should see the states changed to **Resolved**. If this does not occur due to UI changes, then browse back to the **Configured** tab.
![On the Virtual machines screen, several virtual machines have their State listed as Resolved.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image11.png "View the state change")
@ -158,7 +156,7 @@ Synopsis: In this exercise, attendees will secure a Privileged Access Workstatio
![On is highlighted under Toggle for all four of the ports listed under paw-1.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image13.png "Select on for each of the ports")
4. At the bottom of the dialog, select **Open ports**. After a few moments, you should now see the **APPROVED** requests have been incremented and the **LAST ACCESS** is set to **Active now.**.
4. At the bottom of the dialog, select **Open ports**. After a few moments, you should now see the **APPROVED** requests have been incremented and the **Last Access** is set to **Active now.**.
![On the Virtual machines screen, 1 Requests and Active now are highlighted under Aproved and Last Access next to the paw-1 virtual machine.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image14.png "View Approved and Last Access status")
@ -168,13 +166,15 @@ Synopsis: In this exercise, attendees will secure a Privileged Access Workstatio
![Activity Log is highlighted in the shortcut menu for the last user.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image15.png "View the Activity Log")
> **NOTE** These entries will persist after you have deleted the VMs. You will need to manually remove them after VM deletion.
6. In the Azure Portal main menu, select **All Services**, then type **Network**, then select **Network security groups**.
![Network security groups is highlighted on the left side of the Azure portal, and paw-1-nsg is highlighted to the right.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image16.png "Select paw-1-nsg")
7. Select the **paw-1-nsg** network security group.
7. In the filter textbox, type **paw-1-nsg**, then select the **paw-1-nsg** network security group.
8. Select **Inbound security rules.** You should now see a set of inbound security rules set up by JIT Access.
8. Select **Inbound security rules.** You should now see inbound security rules set up by JIT Access.
![The first four listed items are highlighted under Inbound security rules.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image17.png "View the inbound security rules set up by JIT Access")
@ -204,7 +204,7 @@ Synopsis: In this exercise, attendees will utilize Azure SQL features to data ma
![The Server parameter is listed under ADO.NET (SQL authentication) on the ADO.NET tab.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image21.png "Note the Server parameter")
6. Open **SQL Server Management Studio**.
6. In the Lab VM, open **SQL Server Management Studio**.
7. Enter the database server name from above.
@ -214,60 +214,64 @@ Synopsis: In this exercise, attendees will utilize Azure SQL features to data ma
![The information above is entered in the Connect to Server dialog box, and Connect is highlighted at the bottom.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image22.png "Sign in to the SQL Server Database Engine")
9. Select **Connect**, in the **New Firewall Rule** dialog, select **Sign In**.
9. Depending on how you connected to the Azure SQL environment (inside or outside your vnet), you may be prompted to add a firewall rule. If this occurs, perform the following actions:
10. Sign in with your resource group owner credentials.
a. Select **Connect**, in the **New Firewall Rule** dialog, select **Sign In**.
11. In the dialog, select **OK**, notice how your IP address will be added for connection.
b. Sign in with your resource group owner credentials.
c. In the dialog, select **OK**, notice how your incoming public IP address will be added for connection.
![New Firewall Rule Dialog with your Internet IP Address](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image23.png)
12. Right-click **Databases**, and select **Import Data-tier Application**.
10. Right-click **Databases**, and select **Import Data-tier Application**.
![The Object Explorer shows Import Data-tier Application menu item selected.](media/2019-12-18-16-33-49.png "Import Data-tier Application")
![Introduction is highlighted on the left side of the Import Data-tier Application dialog box, and Next is highlighted at the bottom.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image24.png "Select Import Data-tier Application")
13. In the Introduction dialog, select **Next**.
11. In the Introduction dialog, select **Next**.
14. Select **Browse**, navigate to the extracted **/Hands-on- lab/Database** directory, and select the **Insurance.bacpac** file.
12. Select **Browse**, navigate to the extracted **/Hands-on- lab/Database** directory, and select the **Insurance.bacpac** file.
![Insurance.bacpac is selected in the Browse dialog box.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image25.png "Select Insurance.bacpac")
15. Select **Open**.
13. Select **Open**.
16. On the **Import Settings** dialog, select **Next**.
14. On the **Import Settings** dialog, select **Next**.
17. On the **Database Settings** dialog, select **Next**.
15. On the **Database Settings** dialog, select **Next**.
> **Note**: If you get an error, close and re-open SQL Management Studio try the import again. If that does not work, you may need to download the latest SQL Management Studio from [here](https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-2017). In some instances, the latest version may not work, version 17.3 is known to deploy the package properly. You should also be aware that bacpac files exported from some SQL Server instances cannot be deployed to Azure SQL Servers. We have also included a .bak file of the Insurance database that you can use to restore from.
18. Select **Finish** and the database will deploy to Azure. It may take a few minutes.
16. Select **Finish** and the database will deploy to Azure. It may take a few minutes.
19. Once completed, select **Close**.
17. Once completed, select **Close**.
![Results is highlighted on the left side of the Import Data-tier Application dialog box, and at right, many items are listed under Operation Complete. Next is highlighted at the bottom.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image26.png "View the results")
20. In **SQL Management Studio**, select **File-\>Open-\>File**.
18. In **SQL Management Studio**, select **File-\>Open-\>File**.
![In SQL Management Studio, Open is selected in the File menu, and File is selected in the shortcut menu.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image27.png "Open a file")
21. Browse to the extracted GitHub folder, select the **\\Hands-on lab\\Database\\00\_CreateLogin.sql** file.
19. Browse to the extracted GitHub folder, select the **\\Hands-on lab\\Database\\00\_CreateLogin.sql** file.
22. Ensure that the **master** database is selected.
20. Ensure that the **master** database is selected.
23. Run the script to create a login called **agent**.
21. Run the script to create a login called **agent**.
24. Browse to the extracted folder, select the **\\Hands-on lab\\Database\\01\_CreateUser.sql** file.
22. Browse to the extracted folder, select the **\\Hands-on lab\\Database\\01\_CreateUser.sql** file.
25. Ensure that the **Insurance** database is selected.
23. Ensure that the **Insurance** database is selected.
26. Run the script to create a non-admin user called **agent**.
24. Run the script to create a non-admin user called **agent**.
### Task 2: Test the web application solution
1. In the extracted directory, double-click the **\\Hands-on lab\\WebApp\\InsuranceAPI\\InsuranceAPI.sln** solution file, and Visual Studio will open.
> **NOTE** If prompted, login using your Azure / MSDN account.
2. In the **Solution Explorer**, navigate to and double-click the **Web.config** file to open it.
![Web.config is highlighted under InsuranceAPI in Solution Explorer.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image28.png "Open Web.config")
@ -280,7 +284,7 @@ Synopsis: In this exercise, attendees will utilize Azure SQL features to data ma
> **Note** If you get an CSC error, right-click the project, select **Clean**. Next, right-click the project and select **Rebuild**.
5. Test the API for a response. You should see several records returned to the browser. Your port number may be different from _24448_. Copy a `UserId` value for the next instruction.
5. Test the API for a response by browsing to `http://localhost:24448/api/Users`. Your port number may be different from _24448_. You should see several records returned to the browser. Copy a `UserId` value for the next instruction.
![The sample JSON response is returned.](media/2019-12-18-16-59-47.png "Sample JSON Response")
@ -362,27 +366,31 @@ Synopsis: In this exercise, attendees will utilize Azure SQL features to data ma
![The check box next to the SSN column is selected and highlighted, and Deterministic is highlighted under Encryption Type.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image37.png "Select Deterministic")
17. Select **Next**.
> **Deterministic** encryption always generates the same encrypted value for any given plain text value. Using deterministic encryption allows point lookups, equality joins, grouping and indexing on encrypted columns. However, it may also allow unauthorized users to guess information about encrypted values by examining patterns in the encrypted column, especially if there's a small set of possible encrypted values, such as True/False, or North/South/East/West region. Deterministic encryption must use a column collation with a binary2 sort order for character columns.
18. For the encryption select **Azure Key Vault** in the dialog.
> **Randomized** encryption uses a method that encrypts data in a less predictable manner. Randomized encryption is more secure, but prevents searching, grouping, indexing, and joining on encrypted columns.
1. Select **Next**.
2. For the encryption select **Azure Key Vault** in the dialog.
![Azure Key Vault is selected and highlighted under Select the key store provider.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image38.png "Select Azure Key Vault")
19. Select **Sign In**.
3. Select **Sign In**.
20. Sign in with your Azure Portal credentials.
4. Sign in with your Azure Portal credentials.
21. Select your Azure Key Vault.
5. Select your Azure Key Vault.
22. Select **Next**.
6. Select **Next**.
23. On the **Run Settings**, select **Next**.
7. On the **Run Settings**, select **Next**.
24. Select **Finish**, and the configured will start.
8. Select **Finish**, and the configured will start.
> **Note**: You may receive a "wrapKey" error. If so, ensure that your account has been assigned that permission in the Azure Key Vault.
![Generate new column master key CMK\_Auto1 in Azure Key Vault paassecurity is highlighted with a green check mark at the top of the Task Summary list.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image39.png "View the task summary")
![Generate new column master key CMK\_Auto1 in Azure Key Vault is highlighted with a green check mark at the top of the Task Summary list.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image39.png "View the task summary")
- Select **Key vault**.
@ -412,9 +420,9 @@ Synopsis: In this exercise, attendees will utilize Azure SQL features to data ma
![Results is highlighted on the left side of the Always Encrypted dialog box, and at right, Performing encryption operations is selected under Summary: Task. Performing encryption operations has a green check mark and is listed as Passed under Details.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image41.png "View the task results")
25. Select **Close**.
9. Select **Close**.
26. Right-click the **User** table, and choose **Select top 1000 rows**.
10. Right-click the **User** table, and choose **Select top 1000 rows**.
![The User table is selected, and Select Top 1000 Rows is selected in the shortcut menu.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image42.png "Select the top 1000 rows")
@ -422,11 +430,11 @@ Synopsis: In this exercise, attendees will utilize Azure SQL features to data ma
![The value under UserId is selected on the Results tab.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image43.png "Notice the SSN column")
27. Switch to the Azure Portal.
11. Switch to the Azure Portal.
28. Select **Key Vaults**.
12. Select **Key Vaults**.
29. Select your Azure Key Vault, and then select **Keys**. You should see the key created from the SQL Management Studio displayed:
13. Select your Azure Key Vault, and then select **Keys**. You should see the key created from the SQL Management Studio displayed:
![CloudSecurityVault is selected on the left, Keys is selected and highlighted under Settings in the middle, and CMKAuto1 is selected and highlighted under Unmanaged on the right.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image44.png "Select your Azure Key Vault")
@ -570,6 +578,8 @@ Synopsis: In this exercise, attendees will learn how to migrate web application
8. Save the Web.config file in Visual Studio.
> **NOTE** You can take this lab a step further and publish the Web App to an Azure App Service and enable [System-assigned Managed Identities](https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet). This will allow you to completely remove any authentication from your configurations and utilize [Key Vault references](https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references).
### Task 5: Test the solution
1. Open the **Web.config**, and comment out or delete the **connectionString** from the file at line 78.
@ -586,11 +596,26 @@ Synopsis: In this exercise, attendees will learn how to migrate web application
4. Press **F5** to continue the program.
5. Navigate to [http://localhost:portno/api/Users](http://localhost:portno/api/Users), you should get an error. Because you encrypted the column in the previous exercise, EntityFramework is not able to retrieve the value. You would need to:
5. Navigate to [http://localhost:portno/api/Users](http://localhost:portno/api/Users), you should get an error. Because you encrypted the column in the previous exercise, EntityFramework is not able to retrieve the value(s) using default settings. In order to do seamless decryption, you would need to:
- Run the **\\Hands-on lab\\Database\\02\_PermissionSetup.sql** script.
- Run the **\\Hands-on lab\\Database\\02\_PermissionSetup.sql** script if you have not already done so.
- Add the [AzureKeyVaultProvider for Entity Framework](https://blogs.msdn.microsoft.com/sqlsecurity/2015/11/10/using-the-azure-key-vault-key-store-provider-for-always-encrypted/) reference to the project and then register the provider code in order for .NET to handle the encrypted column and add the `Column Encryption Setting=Enabled` to the connection string.
- Add the [AzureKeyVaultProvider for Entity Framework](https://blogs.msdn.microsoft.com/sqlsecurity/2015/11/10/using-the-azure-key-vault-key-store-provider-for-always-encrypted/) reference to the project.
- Register the provider code in order for .NET to handle the encrypted column.
- Add an access policy to the Azure Key Vault that gives key permissions (`decrypt`, `sign`, `get`, `unwrapkey`, `verify`) to the Azure AD application.
- Add the `Column Encryption Setting=Enabled` to the connection string.
- Detailed steps can be found in this [blog post](https://docs.microsoft.com/en-us/archive/blogs/sqlsecurity/using-the-azure-key-vault-key-store-provider-for-always-encrypted)
- A third solution (**\\Hands-on lab\\WebApp\\InsuranceAPI\_KeyVault\_Encrypted\\InsuranceAPI.sln**) was added to the GitHub repo that has the necessary references and code added.
- Simply update the web.config file with your client id and secret after adding the required Key Vault permissions above.
- Update the Key Vault connection string to have the `Column Encryption Setting=Enabled`
- Review the code added to the global.asax.cs file.
- Run the project and navigate to the above page
## Exercise 4: Securing the network
@ -624,7 +649,7 @@ Synopsis: In this exercise, attendees will utilize Network Security Groups to en
6. In the dialog, select **Yes**.
7. Select **File-\>Open**, browse to the extracted GitHub directory and open the **\\Hands-on lab\\Scripts \\PortScanner.ps1**.
7. Select **File-\>Open**, browse to the extracted GitHub directory and open the **\\Hands-on lab\\Scripts\\PortScanner.ps1**.
> **Note**: You would have downloaded the [GitHub repo](https://github.com/Microsoft/MCW-Azure-Security-Privacy-and-Compliance) and extracted this in the setup steps. If you did not perform those steps, perform them now. You can also choose to copy the file from your desktop to the VM.
@ -812,21 +837,25 @@ Synopsis: In this exercise, attendees will utilize Network Security Groups to en
![Packet capture is selected and highlighted on the left under Network Diagnostic Tools, and + Add is highlighted at the top right.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image69.png "Add a packet capture")
7. For the target virtual machine, ensure that **db-1** is selected.
7. Select your subscription
8. For the capture name, enter **databasetraffic**.
8. Select your resource group
9. Notice the ability to save the capture file to the local machine or an Azure storage account. Ensure that the resource group storage account is selected. If you check your resource group, the storage account is prefixed with **"diagstor"**.
9. For the target virtual machine, ensure that **db-1** is selected.
10. For the capture name, enter **databasetraffic**.
11. Notice the ability to save the capture file to the local machine or an Azure storage account. Ensure that the resource group storage account is selected. If you check your resource group, the storage account is prefixed with **"diagstor"**.
![In this screenshot, databasetraffic is entered in the Packet capture name box, and the Storage account check box is selected.](media/2020-01-12-12-24-05.png "Dialog box screenshot")
10. For the values, enter the following:
12. For the values, enter the following:
- Maximum bytes per packet: 0
- Maximum bytes per session: 1073741824
- Time limit: 600
11. Select **OK**.
13. Select **OK**.
### Task 6: Execute a port scan
@ -858,18 +887,20 @@ Synopsis: In this exercise, you will setup Azure Sentinel to point to a logging
4. In the blade, under **Threat Management**, select **Workbooks**.
5. In the list of workbooks, select **Azure AD Audit logs**, select **Save**.
5. In the list of workbooks, select **Azure Network Watcher**, choose **Save**.
6. Select the region and select **OK**.
6. Select the region and choose **OK**.
7. In the list of workbooks, select **Azure AD Audit logs**, select **Save**.
8. Select the region and select **OK**.
![In this screenshot, Dashboards has been selected and the Azure AD Audit Logs dashboard has also been selected.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image95.png "Adding a workbooks")
7. In the list of dashboards, select **Azure Network Watcher**, choose **Save**.
8. Select the region and choose **OK**.
9. Select **View saved workbook**, take a moment to review your new workbook.
> **NOTE** You may not have data in the log analytics workspace. Wait for 10-15 minutes.
### Task 2: Create an Analytics alert
1. Navigate back to the **Azure Sentinel** workspace, in the **Configuration** blade section, select **Analytics** then select **+Create** then **Scheduled query rule**.
@ -880,17 +911,22 @@ Synopsis: In this exercise, you will setup Azure Sentinel to point to a logging
3. For the description, enter **A custom rule to detect port scans**, select **Next: Set rule logic**.
4. In the **Set alert query** text box, type:
4. In the **Rule query** text box, type:
```powershell
AzureDiagnostics | where Type != 'AzureMetric' and OperationName == 'NetworkSecurityGroupCounters' and type_s == 'block' and direction_s == 'In' and Resource == 'WEBTRAFFICONLY' and TimeGenerated > ago(1h)
```
```powershell
AzureDiagnostics
| where ruleName_s == 'UserRule_DenyAll' and Type != 'AzureMetric' and type_s == 'block' and direction_s == 'In' and Resource == 'WEBTRAFFICONLY' and OperationName == 'NetworkSecurityGroupCounters'
| summarize AggregatedValue = sum(matchedConnections_d) by ruleName_s, primaryIPv4Address_s
| where AggregatedValue > 0
```
![In this screenshot, the alert simulation shows data after the query has been entered.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image97.png "Reviewing alert simulation data")
> **Note**: If you were quick going through the labs, then you may not have log data in the Log Analytics workspace just yet that corresponds to "AzureMetric". You may need to wait 15-30 minutes before a query will execute.
> **Note**: If you were quick going through the labs, then you may not have log data in the Log Analytics workspace just yet that corresponds to "AzureMetric". You may need to wait 15-30 minutes before a query will execute.
5. Under **Map entities**, for the **IP address**, select **conditions_sourceIP_s** and then select **Add**.
> **Note**: Since the introduction of Azure Security Center and Sentinel, the backend logging has changed a few times as well as the way the calculations are done in the rule query (timespan in query vs outside query, etc). The ultimate goal of this query is to find when a series of failed connection attempts have been made against a network security group and a specific deny rule. If for some reason the UI/backend has been modified since the last published lab, modify the query to accomplish this goal.
5. Under **Map entities**, for the **IP**, select the **primaryIPv4Address_s** column.
6. Under **Query scheduling**, for the **Run query every** setting, type **5** minutes.
@ -898,23 +934,19 @@ Synopsis: In this exercise, you will setup Azure Sentinel to point to a logging
7. For the **Lookup data from the last**, type **1** hours.
8. Under **Alert threshold**, for the **Generate alert when number of query results**, enter **15**.
8. Under **Alert threshold**, for the **Generate alert when number of query results**, enter **1**.
> **Note:** We want to hit the threshold quickly for lab purposes. This value may not be appropriate for production.
> **Note:** We want to hit the threshold quickly for lab purposes. This query and value may not be appropriate for production and is only for learning purposes.
Review the current data to determine what would trigger the alert. Notice the red threshold line intersects the blue event data line.
![Displaying the current log data and the alert threshold.](media/2020-01-12-13-26-17.png "Results Preview")
9. For the suppress alerts for, enter **5** and **Minutes**.
9. Select **Next: Automated response**, notice you have no playbooks to select yet.
![The above information is entered in the dialog box for the new custom analytics rule.](media/2020-01-12-13-18-04.png "Rule dialog box")
10. Select **Next: Review**.
10. Select **Next: Automated response**.
11. Select **Next: Review**.
12. Select **Create**.
11. Select **Create**.
> **Note**: It may take a few minutes for the alert to fire. You may need to run the PortScan script a few times from **paw-1**
@ -944,7 +976,7 @@ Synopsis: In this exercise, you will setup Azure Sentinel to point to a logging
1. In the **Azure Sentinel** blade, select **Playbooks**.
2. In the new window, select **Add Playbook**.
2. In the new window, select **+ Add Playbook**.
![Screen shot of the playbooks blade with the Playbooks and Add Playbook links highlighted.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image79.png)
@ -970,29 +1002,33 @@ Synopsis: In this exercise, you will setup Azure Sentinel to point to a logging
![The Use this template button is selected under Send notification email with alert details from Azure Security Center.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image82.png "Select Use this template")
7. Select **Sign In**, and then type your Azure/O365 credentials.
7. For the **Office 365 Outlook** connection, select the **+** link, enter your Azure/O365 credentials.
![The Sign in button is highlighted next to Office 365 Outlook under This logic app will connect to.](media/2020-01-12-14-48-03.png "Sign in to Office 365 Outlook")
> **Note**: This would need to be a valid Office 365 account, if you do not have a valid Office 365 account, then utilize a basic email template for Outlook.com.
8. Select **Continue**.
8. For the **Security Center Alert** connection, select the **+** link
9. Select **Continue**.
![The Logic app connection blade is displayed. Outlook and Azure Security Center validation are displayed.](media/2020-01-12-14-51-29.png "Logic App Connection Information")
9. For the email address, enter your email.
10. For the email address, enter your email.
10. Select **Save**. You now have an email alert action based on LogicApps for your custom security alert to use.
11. Select **Save**. You now have an email alert action based on LogicApps for your custom security alert to use.
![Save is highlighted in Logic Apps Designer, and information about the custom security alert appears below.](media/2020-01-12-14-54-20.png "Save the email alert action")
11. Lastly, after you have created the new Playbook, ensure that the status is **Enabled**. If not, then select **Enable** in the menu.
12. Lastly, after you have created the new Playbook, ensure that the status is **Enabled**. If not, then select **Enable** in the menu.
### Task 5: Execute Jupyter Notebooks
1. In the **Azure Sentinel** blade, select **Notebooks**.
2. Scroll to the bottom of the page and select **Clone Notebooks**.
2. In the blade top menu navigation, select **Clone Notebooks**.
3. If not already logged in, select your Azure credentials, the GitHub repo will start to clone into your workspace.
![Azure Sentinel Notebooks blade shows Clone Notebooks is highlighted.](media/2020-01-12-18-02-39.png "Close Azure Sentinel Notebooks")
@ -1000,17 +1036,17 @@ Synopsis: In this exercise, you will setup Azure Sentinel to point to a logging
![The GitHub progress meter is displayed.](media/2020-01-12-18-06-26.png "GitHub Progress Meter")
3. Navigate to **My Projects** and select the **Run on Free Compute**.
4. Navigate to **My Projects** and select the **Run on Free Compute**.
4. Find **Get Started.ipynb**. You may have to page through the results to find the **Get Started.ipynb** notebook. Select it. In this example, it was located on the second page.
5. Search for the **Get Started.ipynb** notebook. You may have to page through the results to find the **Get Started.ipynb** notebook. Select it. In this example, it was located on the second page.
![My Project is displayed. The Get Started notebook is selected.](media/2020-01-12-18-08-26.png "My Projects Notebook List")
5. In the menu, select **Kernel->Change kernel**, then select **Python 3.6**.
6. In the menu, select **Kernel->Change kernel**, then select **Python 3.6**.
![The page menu is expanded to the Kernel menu item and the change kernel with Python 3.6 is selected.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image102.png "Set the Kernel to Python 3.6")
6. Choose the **Run** button until you execute the entire Notebook, note that some steps will required your input.
7. Choose the **Run** button until you execute the entire Notebook, note that some steps will required your input.
When the cell has an asterisk, it is still processing. Wait for a number to appear.
@ -1081,6 +1117,8 @@ Synopsis: In this exercise, attendees will learn to navigate the Azure Policy an
6. In the filter search box, type **PAW-1** and select it when displayed.
> **NOTE** You may not see resources display right away. If this is the case, then scroll through some other non-compliant resources.
7. With the **Policies** tab selected, review the policies that the resource is non-complying against.
>**Note**: New policies are being created and your number may be different from the image below.
@ -1095,11 +1133,11 @@ Synopsis: In this exercise, attendees will learn to navigate the Azure Policy an
### Task 2: Review and create Azure Blueprints
1. In the Policy blade, select **Definitions**. These are a list of all defined policies which can be selected for assignment to your subscription resources.
1. In the Policy blade, under **Authoring**, select **Definitions**. These are a list of all defined policies which can be selected for assignment to your subscription resources.
![A listing of policy definitions on the Policy Blade Definitions](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image109.png "Review available policy definitions")
2. In the Policy blade, select **Blueprints**.
2. In the Policy blade, under **Related Services**, select **Blueprints**.
3. In the Blueprints blade, select **Blueprint definitions**.
@ -1121,7 +1159,7 @@ Synopsis: In this exercise, attendees will learn to navigate the Azure Policy an
9. Select **Next: Artifacts**.
10. Select **+Add artifact**.
10. Select **+ Add artifact**.
11. For the Artifact Type, select **Policy Assignment**, review all the policies available to you (at the time of this writing you would see 37 definitions and 311 policies).
@ -1151,13 +1189,13 @@ Synopsis: In this exercise, attendees will learn to navigate the Azure Policy an
1. In the Azure Portal, select **All Services**, then type **Security**, select **Security Center**.
2. In the Security Center blade, select **Secure score**.
2. In the Security Center blade, under **POLICY & COMPLIANCE**, select **Secure score**.
3. Review your overall secure score values and then notice the category values.
![Screen shot showing Secure score blade and the score and categories highlighted.](images/Hands-onlabstep-bystep-Azuresecurityprivacyandcomplianceimages/media/image115.png "Review Secure Score score and categories")
4. Select your subscription, you will be presented with the items that have failed resource validation sorted by the score value that is assigned to that particular recommendation item.
4. On the bottom half of the window, select your subscription, you will be presented with the items that have failed resource validation sorted by the score value that is assigned to that particular recommendation item.
5. Select the **An Azure Active Directory administrator should be provisioned for SQL Servers**, on the recommendation blade, you will be presented with information about how to remediate the recommendation to gain the impact value to your score.
@ -1211,7 +1249,7 @@ Synopsis: In this exercise, attendees will learn to navigate the Azure Policy an
Duration: 10 minutes
In this exercise, attendees will deprovision any Azure resources that were created in support of the lab.
In this exercise, attendees will un-provision any Azure resources that were created in support of the lab.
### Task 1: Delete resource group

Просмотреть файл

@ -507,13 +507,13 @@
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2016-Datacenter",
"publisher": "microsoftvisualstudio",
"offer": "visualstudio2019latest",
"sku": "vs-2019-comm-latest-ws2019",
"version": "latest"
},
},
"osDisk": {
"createOption": "fromImage",
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
}
@ -567,12 +567,12 @@
},
{
"name": "paw-1-ip",
"type": "Microsoft.Network/publicIpAddresses",
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2017-08-01",
"location": "[resourceGroup().location]",
"properties": {
"publicIPAddressVersion": "IPv4",
"publicIpAllocationMethod": "Dynamic"
"publicIPAllocationMethod": "Dynamic"
}
},
{
@ -604,7 +604,7 @@
"version": "latest"
},
"osDisk": {
"createOption": "fromImage",
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
}
@ -681,7 +681,7 @@
"version": "latest"
},
"osDisk": {
"createOption": "fromImage",
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
}

Просмотреть файл

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InsuranceAPI_KeyVault_Encrypted", "InsuranceAPI\InsuranceAPI_KeyVault_Encrypted.csproj", "{EB449E3C-3C97-468F-B78C-AF1204CA11D5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EB449E3C-3C97-468F-B78C-AF1204CA11D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB449E3C-3C97-468F-B78C-AF1204CA11D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB449E3C-3C97-468F-B78C-AF1204CA11D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB449E3C-3C97-468F-B78C-AF1204CA11D5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9E42F838-BE24-4BAC-828B-F6814C0EAB48}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InsuranceAPI
{
using System;
using System.Collections.Generic;
public partial class Accident
{
public int ReportNumber { get; set; }
public Nullable<System.Guid> VehicleId { get; set; }
public Nullable<System.Guid> UserId { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public Nullable<System.DateTime> Date { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
public Nullable<System.DateTime> ModifyDate { get; set; }
public Nullable<System.DateTime> DeleteDate { get; set; }
public virtual User User { get; set; }
public virtual Vehicle Vehicle { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InsuranceAPI
{
using System;
using System.Collections.Generic;
public partial class Agent
{
public System.Guid AgentId { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public Nullable<System.DateTime> ModifyDate { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,28 @@
using System.Web;
using System.Web.Optimization;
namespace InsuranceAPI
{
public class BundleConfig
{
// For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
using System.Web;
using System.Web.Mvc;
namespace InsuranceAPI
{
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace InsuranceAPI
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace InsuranceAPI
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}

Просмотреть файл

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
<TelemetryInitializers>
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.HttpDependenciesParsingTelemetryInitializer, Microsoft.AI.DependencyCollector"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureRoleEnvironmentTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureWebAppRoleEnvironmentTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.BuildInfoConfigComponentVersionTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.Web.WebTestTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.SyntheticUserAgentTelemetryInitializer, Microsoft.AI.Web">
<!-- Extended list of bots:
search|spider|crawl|Bot|Monitor|BrowserMob|BingPreview|PagePeeker|WebThumb|URL2PNG|ZooShot|GomezA|Google SketchUp|Read Later|KTXN|KHTE|Keynote|Pingdom|AlwaysOn|zao|borg|oegp|silk|Xenu|zeal|NING|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|Java|JNLP|Daumoa|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|vortex|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|voyager|archiver|Icarus6j|mogimogi|Netvibes|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|wsr-agent|http client|Python-urllib|AppEngine-Google|semanticdiscovery|facebookexternalhit|web/snippet|Google-HTTP-Java-Client-->
<Filters>search|spider|crawl|Bot|Monitor|AlwaysOn</Filters>
</Add>
<Add Type="Microsoft.ApplicationInsights.Web.ClientIpHeaderTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.OperationNameTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.OperationCorrelationTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.UserTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.AuthenticatedUserIdTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.AccountIdTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.SessionTelemetryInitializer, Microsoft.AI.Web"/>
</TelemetryInitializers>
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector">
<ExcludeComponentCorrelationHttpHeadersOnDomains>
<!--
Requests to the following hostnames will not be modified by adding correlation headers.
Add entries here to exclude additional hostnames.
NOTE: this configuration will be lost upon NuGet upgrade.
-->
<Add>core.windows.net</Add>
<Add>core.chinacloudapi.cn</Add>
<Add>core.cloudapi.de</Add>
<Add>core.usgovcloudapi.net</Add>
</ExcludeComponentCorrelationHttpHeadersOnDomains>
<IncludeDiagnosticSourceActivities>
<Add>Microsoft.Azure.EventHubs</Add>
<Add>Microsoft.Azure.ServiceBus</Add>
</IncludeDiagnosticSourceActivities>
</Add>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
<!--
Use the following syntax here to collect additional performance counters:
<Counters>
<Add PerformanceCounter="\Process(??APP_WIN32_PROC??)\Handle Count" ReportAs="Process handle count" />
...
</Counters>
PerformanceCounter must be either \CategoryName(InstanceName)\CounterName or \CategoryName\CounterName
NOTE: performance counters configuration will be lost upon NuGet upgrade.
The following placeholders are supported as InstanceName:
??APP_WIN32_PROC?? - instance name of the application process for Win32 counters.
??APP_W3SVC_PROC?? - instance name of the application IIS worker process for IIS/ASP.NET counters.
??APP_CLR_PROC?? - instance name of the application CLR process for .NET counters.
-->
</Add>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse.QuickPulseTelemetryModule, Microsoft.AI.PerfCounterCollector"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AppServicesHeartbeatTelemetryModule, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureInstanceMetadataTelemetryModule, Microsoft.AI.WindowsServer">
<!--
Remove individual fields collected here by adding them to the ApplicationInsighs.HeartbeatProvider
with the following syntax:
<Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights">
<ExcludedHeartbeatProperties>
<Add>osType</Add>
<Add>location</Add>
<Add>name</Add>
<Add>offer</Add>
<Add>platformFaultDomain</Add>
<Add>platformUpdateDomain</Add>
<Add>publisher</Add>
<Add>sku</Add>
<Add>version</Add>
<Add>vmId</Add>
<Add>vmSize</Add>
<Add>subscriptionId</Add>
<Add>resourceGroupName</Add>
<Add>placementGroupId</Add>
<Add>tags</Add>
<Add>vmScaleSetName</Add>
</ExcludedHeartbeatProperties>
</Add>
NOTE: exclusions will be lost upon upgrade.
-->
</Add>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DeveloperModeWithDebuggerAttachedTelemetryModule, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.UnhandledExceptionTelemetryModule, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.UnobservedExceptionTelemetryModule, Microsoft.AI.WindowsServer">
<!--</Add>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.FirstChanceExceptionStatisticsTelemetryModule, Microsoft.AI.WindowsServer">-->
</Add>
<Add Type="Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule, Microsoft.AI.Web">
<Handlers>
<!--
Add entries here to filter out additional handlers:
NOTE: handler configuration will be lost upon NuGet upgrade.
-->
<Add>Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler</Add>
<Add>System.Web.StaticFileHandler</Add>
<Add>System.Web.Handlers.AssemblyResourceLoader</Add>
<Add>System.Web.Optimization.BundleHandler</Add>
<Add>System.Web.Script.Services.ScriptHandlerFactory</Add>
<Add>System.Web.Handlers.TraceHandler</Add>
<Add>System.Web.Services.Discovery.DiscoveryRequestHandler</Add>
<Add>System.Web.HttpDebugHandler</Add>
</Handlers>
</Add>
<Add Type="Microsoft.ApplicationInsights.Web.ExceptionTrackingTelemetryModule, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.AspNetDiagnosticTelemetryModule, Microsoft.AI.Web"/>
</TelemetryModules>
<ApplicationIdProvider Type="Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId.ApplicationInsightsApplicationIdProvider, Microsoft.ApplicationInsights"/>
<TelemetrySinks>
<Add Name="default">
<TelemetryProcessors>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse.QuickPulseTelemetryProcessor, Microsoft.AI.PerfCounterCollector"/>
<Add Type="Microsoft.ApplicationInsights.Extensibility.AutocollectedMetricsExtractor, Microsoft.ApplicationInsights"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.AdaptiveSamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel">
<MaxTelemetryItemsPerSecond>5</MaxTelemetryItemsPerSecond>
<ExcludedTypes>Event</ExcludedTypes>
</Add>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.AdaptiveSamplingTelemetryProcessor, Microsoft.AI.ServerTelemetryChannel">
<MaxTelemetryItemsPerSecond>5</MaxTelemetryItemsPerSecond>
<IncludedTypes>Event</IncludedTypes>
</Add>
</TelemetryProcessors>
<TelemetryChannel Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel, Microsoft.AI.ServerTelemetryChannel"/>
</Add>
</TelemetrySinks>
<!--
Learn more about Application Insights configuration with ApplicationInsights.config here:
http://go.microsoft.com/fwlink/?LinkID=513840
Note: If not present, please add <InstrumentationKey>Your Key</InstrumentationKey> to the top of this file.
--></ApplicationInsights>

Просмотреть файл

@ -0,0 +1,39 @@
using System;
using System.Text;
using System.Web;
using System.Web.Http.Description;
namespace InsuranceAPI.Areas.HelpPage
{
public static class ApiDescriptionExtensions
{
/// <summary>
/// Generates an URI-friendly ID for the <see cref="ApiDescription"/>. E.g. "Get-Values-id_name" instead of "GetValues/{id}?name={name}"
/// </summary>
/// <param name="description">The <see cref="ApiDescription"/>.</param>
/// <returns>The ID as a string.</returns>
public static string GetFriendlyId(this ApiDescription description)
{
string path = description.RelativePath;
string[] urlParts = path.Split('?');
string localPath = urlParts[0];
string queryKeyString = null;
if (urlParts.Length > 1)
{
string query = urlParts[1];
string[] queryKeys = HttpUtility.ParseQueryString(query).AllKeys;
queryKeyString = String.Join("_", queryKeys);
}
StringBuilder friendlyPath = new StringBuilder();
friendlyPath.AppendFormat("{0}-{1}",
description.HttpMethod.Method,
localPath.Replace("/", "-").Replace("{", String.Empty).Replace("}", String.Empty));
if (queryKeyString != null)
{
friendlyPath.AppendFormat("_{0}", queryKeyString.Replace('.', '-'));
}
return friendlyPath.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,113 @@
// Uncomment the following to provide samples for PageResult<T>. Must also add the Microsoft.AspNet.WebApi.OData
// package to your project.
////#define Handle_PageResultOfT
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Web;
using System.Web.Http;
#if Handle_PageResultOfT
using System.Web.Http.OData;
#endif
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// Use this class to customize the Help Page.
/// For example you can set a custom <see cref="System.Web.Http.Description.IDocumentationProvider"/> to supply the documentation
/// or you can provide the samples for the requests/responses.
/// </summary>
public static class HelpPageConfig
{
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
MessageId = "InsuranceAPI.Areas.HelpPage.TextSample.#ctor(System.String)",
Justification = "End users may choose to merge this string with existing localized resources.")]
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly",
MessageId = "bsonspec",
Justification = "Part of a URI.")]
public static void Register(HttpConfiguration config)
{
//// Uncomment the following to use the documentation from XML documentation file.
//config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
//// Uncomment the following to use "sample string" as the sample for all actions that have string as the body parameter or return type.
//// Also, the string arrays will be used for IEnumerable<string>. The sample objects will be serialized into different media type
//// formats by the available formatters.
//config.SetSampleObjects(new Dictionary<Type, object>
//{
// {typeof(string), "sample string"},
// {typeof(IEnumerable<string>), new string[]{"sample 1", "sample 2"}}
//});
// Extend the following to provide factories for types not handled automatically (those lacking parameterless
// constructors) or for which you prefer to use non-default property values. Line below provides a fallback
// since automatic handling will fail and GeneratePageResult handles only a single type.
#if Handle_PageResultOfT
config.GetHelpPageSampleGenerator().SampleObjectFactories.Add(GeneratePageResult);
#endif
// Extend the following to use a preset object directly as the sample for all actions that support a media
// type, regardless of the body parameter or return type. The lines below avoid display of binary content.
// The BsonMediaTypeFormatter (if available) is not used to serialize the TextSample object.
config.SetSampleForMediaType(
new TextSample("Binary JSON content. See http://bsonspec.org for details."),
new MediaTypeHeaderValue("application/bson"));
//// Uncomment the following to use "[0]=foo&[1]=bar" directly as the sample for all actions that support form URL encoded format
//// and have IEnumerable<string> as the body parameter or return type.
//config.SetSampleForType("[0]=foo&[1]=bar", new MediaTypeHeaderValue("application/x-www-form-urlencoded"), typeof(IEnumerable<string>));
//// Uncomment the following to use "1234" directly as the request sample for media type "text/plain" on the controller named "Values"
//// and action named "Put".
//config.SetSampleRequest("1234", new MediaTypeHeaderValue("text/plain"), "Values", "Put");
//// Uncomment the following to use the image on "../images/aspNetHome.png" directly as the response sample for media type "image/png"
//// on the controller named "Values" and action named "Get" with parameter "id".
//config.SetSampleResponse(new ImageSample("../images/aspNetHome.png"), new MediaTypeHeaderValue("image/png"), "Values", "Get", "id");
//// Uncomment the following to correct the sample request when the action expects an HttpRequestMessage with ObjectContent<string>.
//// The sample will be generated as if the controller named "Values" and action named "Get" were having string as the body parameter.
//config.SetActualRequestType(typeof(string), "Values", "Get");
//// Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent<string>.
//// The sample will be generated as if the controller named "Values" and action named "Post" were returning a string.
//config.SetActualResponseType(typeof(string), "Values", "Post");
}
#if Handle_PageResultOfT
private static object GeneratePageResult(HelpPageSampleGenerator sampleGenerator, Type type)
{
if (type.IsGenericType)
{
Type openGenericType = type.GetGenericTypeDefinition();
if (openGenericType == typeof(PageResult<>))
{
// Get the T in PageResult<T>
Type[] typeParameters = type.GetGenericArguments();
Debug.Assert(typeParameters.Length == 1);
// Create an enumeration to pass as the first parameter to the PageResult<T> constuctor
Type itemsType = typeof(List<>).MakeGenericType(typeParameters);
object items = sampleGenerator.GetSampleObject(itemsType);
// Fill in the other information needed to invoke the PageResult<T> constuctor
Type[] parameterTypes = new Type[] { itemsType, typeof(Uri), typeof(long?), };
object[] parameters = new object[] { items, null, (long)ObjectGenerator.DefaultCollectionSize, };
// Call PageResult(IEnumerable<T> items, Uri nextPageLink, long? count) constructor
ConstructorInfo constructor = type.GetConstructor(parameterTypes);
return constructor.Invoke(parameters);
}
}
return null;
}
#endif
}
}

Просмотреть файл

@ -0,0 +1,63 @@
using System;
using System.Web.Http;
using System.Web.Mvc;
using InsuranceAPI.Areas.HelpPage.ModelDescriptions;
using InsuranceAPI.Areas.HelpPage.Models;
namespace InsuranceAPI.Areas.HelpPage.Controllers
{
/// <summary>
/// The controller that will handle requests for the help page.
/// </summary>
public class HelpController : Controller
{
private const string ErrorViewName = "Error";
public HelpController()
: this(GlobalConfiguration.Configuration)
{
}
public HelpController(HttpConfiguration config)
{
Configuration = config;
}
public HttpConfiguration Configuration { get; private set; }
public ActionResult Index()
{
ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
}
public ActionResult Api(string apiId)
{
if (!String.IsNullOrEmpty(apiId))
{
HelpPageApiModel apiModel = Configuration.GetHelpPageApiModel(apiId);
if (apiModel != null)
{
return View(apiModel);
}
}
return View(ErrorViewName);
}
public ActionResult ResourceModel(string modelName)
{
if (!String.IsNullOrEmpty(modelName))
{
ModelDescriptionGenerator modelDescriptionGenerator = Configuration.GetModelDescriptionGenerator();
ModelDescription modelDescription;
if (modelDescriptionGenerator.GeneratedModels.TryGetValue(modelName, out modelDescription))
{
return View(modelDescription);
}
}
return View(ErrorViewName);
}
}
}

Просмотреть файл

@ -0,0 +1,134 @@
.help-page h1,
.help-page .h1,
.help-page h2,
.help-page .h2,
.help-page h3,
.help-page .h3,
#body.help-page,
.help-page-table th,
.help-page-table pre,
.help-page-table p {
font-family: "Segoe UI Light", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif;
}
.help-page pre.wrapped {
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
white-space: pre-wrap;
}
.help-page .warning-message-container {
margin-top: 20px;
padding: 0 10px;
color: #525252;
background: #EFDCA9;
border: 1px solid #CCCCCC;
}
.help-page-table {
width: 100%;
border-collapse: collapse;
text-align: left;
margin: 0px 0px 20px 0px;
border-top: 1px solid #D4D4D4;
}
.help-page-table th {
text-align: left;
font-weight: bold;
border-bottom: 1px solid #D4D4D4;
padding: 5px 6px 5px 6px;
}
.help-page-table td {
border-bottom: 1px solid #D4D4D4;
padding: 10px 8px 10px 8px;
vertical-align: top;
}
.help-page-table pre,
.help-page-table p {
margin: 0px;
padding: 0px;
font-family: inherit;
font-size: 100%;
}
.help-page-table tbody tr:hover td {
background-color: #F3F3F3;
}
.help-page a:hover {
background-color: transparent;
}
.help-page .sample-header {
border: 2px solid #D4D4D4;
background: #00497E;
color: #FFFFFF;
padding: 8px 15px;
border-bottom: none;
display: inline-block;
margin: 10px 0px 0px 0px;
}
.help-page .sample-content {
display: block;
border-width: 0;
padding: 15px 20px;
background: #FFFFFF;
border: 2px solid #D4D4D4;
margin: 0px 0px 10px 0px;
}
.help-page .api-name {
width: 40%;
}
.help-page .api-documentation {
width: 60%;
}
.help-page .parameter-name {
width: 20%;
}
.help-page .parameter-documentation {
width: 40%;
}
.help-page .parameter-type {
width: 20%;
}
.help-page .parameter-annotations {
width: 20%;
}
.help-page h1,
.help-page .h1 {
font-size: 36px;
line-height: normal;
}
.help-page h2,
.help-page .h2 {
font-size: 24px;
}
.help-page h3,
.help-page .h3 {
font-size: 20px;
}
#body.help-page {
font-size: 14px;
line-height: 143%;
color: #333;
}
.help-page a {
color: #0000EE;
text-decoration: none;
}

Просмотреть файл

@ -0,0 +1,26 @@
using System.Web.Http;
using System.Web.Mvc;
namespace InsuranceAPI.Areas.HelpPage
{
public class HelpPageAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "HelpPage";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"HelpPage_Default",
"Help/{action}/{apiId}",
new { controller = "Help", action = "Index", apiId = UrlParameter.Optional });
HelpPageConfig.Register(GlobalConfiguration.Configuration);
}
}
}

Просмотреть файл

@ -0,0 +1,467 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using InsuranceAPI.Areas.HelpPage.ModelDescriptions;
using InsuranceAPI.Areas.HelpPage.Models;
namespace InsuranceAPI.Areas.HelpPage
{
public static class HelpPageConfigurationExtensions
{
private const string ApiModelPrefix = "MS_HelpPageApiModel_";
/// <summary>
/// Sets the documentation provider for help page.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="documentationProvider">The documentation provider.</param>
public static void SetDocumentationProvider(this HttpConfiguration config, IDocumentationProvider documentationProvider)
{
config.Services.Replace(typeof(IDocumentationProvider), documentationProvider);
}
/// <summary>
/// Sets the objects that will be used by the formatters to produce sample requests/responses.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sampleObjects">The sample objects.</param>
public static void SetSampleObjects(this HttpConfiguration config, IDictionary<Type, object> sampleObjects)
{
config.GetHelpPageSampleGenerator().SampleObjects = sampleObjects;
}
/// <summary>
/// Sets the sample request directly for the specified media type and action.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sample">The sample request.</param>
/// <param name="mediaType">The media type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
public static void SetSampleRequest(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName)
{
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Request, controllerName, actionName, new[] { "*" }), sample);
}
/// <summary>
/// Sets the sample request directly for the specified media type and action with parameters.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sample">The sample request.</param>
/// <param name="mediaType">The media type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
public static void SetSampleRequest(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName, params string[] parameterNames)
{
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Request, controllerName, actionName, parameterNames), sample);
}
/// <summary>
/// Sets the sample request directly for the specified media type of the action.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sample">The sample response.</param>
/// <param name="mediaType">The media type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
public static void SetSampleResponse(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName)
{
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Response, controllerName, actionName, new[] { "*" }), sample);
}
/// <summary>
/// Sets the sample response directly for the specified media type of the action with specific parameters.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sample">The sample response.</param>
/// <param name="mediaType">The media type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
public static void SetSampleResponse(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, string controllerName, string actionName, params string[] parameterNames)
{
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, SampleDirection.Response, controllerName, actionName, parameterNames), sample);
}
/// <summary>
/// Sets the sample directly for all actions with the specified media type.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sample">The sample.</param>
/// <param name="mediaType">The media type.</param>
public static void SetSampleForMediaType(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType)
{
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType), sample);
}
/// <summary>
/// Sets the sample directly for all actions with the specified type and media type.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sample">The sample.</param>
/// <param name="mediaType">The media type.</param>
/// <param name="type">The parameter type or return type of an action.</param>
public static void SetSampleForType(this HttpConfiguration config, object sample, MediaTypeHeaderValue mediaType, Type type)
{
config.GetHelpPageSampleGenerator().ActionSamples.Add(new HelpPageSampleKey(mediaType, type), sample);
}
/// <summary>
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> passed to the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
/// The help page will use this information to produce more accurate request samples.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="type">The type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
public static void SetActualRequestType(this HttpConfiguration config, Type type, string controllerName, string actionName)
{
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Request, controllerName, actionName, new[] { "*" }), type);
}
/// <summary>
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> passed to the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
/// The help page will use this information to produce more accurate request samples.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="type">The type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
public static void SetActualRequestType(this HttpConfiguration config, Type type, string controllerName, string actionName, params string[] parameterNames)
{
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Request, controllerName, actionName, parameterNames), type);
}
/// <summary>
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> returned as part of the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
/// The help page will use this information to produce more accurate response samples.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="type">The type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
public static void SetActualResponseType(this HttpConfiguration config, Type type, string controllerName, string actionName)
{
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Response, controllerName, actionName, new[] { "*" }), type);
}
/// <summary>
/// Specifies the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> returned as part of the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
/// The help page will use this information to produce more accurate response samples.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="type">The type.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
public static void SetActualResponseType(this HttpConfiguration config, Type type, string controllerName, string actionName, params string[] parameterNames)
{
config.GetHelpPageSampleGenerator().ActualHttpMessageTypes.Add(new HelpPageSampleKey(SampleDirection.Response, controllerName, actionName, parameterNames), type);
}
/// <summary>
/// Gets the help page sample generator.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <returns>The help page sample generator.</returns>
public static HelpPageSampleGenerator GetHelpPageSampleGenerator(this HttpConfiguration config)
{
return (HelpPageSampleGenerator)config.Properties.GetOrAdd(
typeof(HelpPageSampleGenerator),
k => new HelpPageSampleGenerator());
}
/// <summary>
/// Sets the help page sample generator.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="sampleGenerator">The help page sample generator.</param>
public static void SetHelpPageSampleGenerator(this HttpConfiguration config, HelpPageSampleGenerator sampleGenerator)
{
config.Properties.AddOrUpdate(
typeof(HelpPageSampleGenerator),
k => sampleGenerator,
(k, o) => sampleGenerator);
}
/// <summary>
/// Gets the model description generator.
/// </summary>
/// <param name="config">The configuration.</param>
/// <returns>The <see cref="ModelDescriptionGenerator"/></returns>
public static ModelDescriptionGenerator GetModelDescriptionGenerator(this HttpConfiguration config)
{
return (ModelDescriptionGenerator)config.Properties.GetOrAdd(
typeof(ModelDescriptionGenerator),
k => InitializeModelDescriptionGenerator(config));
}
/// <summary>
/// Gets the model that represents an API displayed on the help page. The model is initialized on the first call and cached for subsequent calls.
/// </summary>
/// <param name="config">The <see cref="HttpConfiguration"/>.</param>
/// <param name="apiDescriptionId">The <see cref="ApiDescription"/> ID.</param>
/// <returns>
/// An <see cref="HelpPageApiModel"/>
/// </returns>
public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, string apiDescriptionId)
{
object model;
string modelId = ApiModelPrefix + apiDescriptionId;
if (!config.Properties.TryGetValue(modelId, out model))
{
Collection<ApiDescription> apiDescriptions = config.Services.GetApiExplorer().ApiDescriptions;
ApiDescription apiDescription = apiDescriptions.FirstOrDefault(api => String.Equals(api.GetFriendlyId(), apiDescriptionId, StringComparison.OrdinalIgnoreCase));
if (apiDescription != null)
{
model = GenerateApiModel(apiDescription, config);
config.Properties.TryAdd(modelId, model);
}
}
return (HelpPageApiModel)model;
}
private static HelpPageApiModel GenerateApiModel(ApiDescription apiDescription, HttpConfiguration config)
{
HelpPageApiModel apiModel = new HelpPageApiModel()
{
ApiDescription = apiDescription,
};
ModelDescriptionGenerator modelGenerator = config.GetModelDescriptionGenerator();
HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
GenerateUriParameters(apiModel, modelGenerator);
GenerateRequestModelDescription(apiModel, modelGenerator, sampleGenerator);
GenerateResourceDescription(apiModel, modelGenerator);
GenerateSamples(apiModel, sampleGenerator);
return apiModel;
}
private static void GenerateUriParameters(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator)
{
ApiDescription apiDescription = apiModel.ApiDescription;
foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions)
{
if (apiParameter.Source == ApiParameterSource.FromUri)
{
HttpParameterDescriptor parameterDescriptor = apiParameter.ParameterDescriptor;
Type parameterType = null;
ModelDescription typeDescription = null;
ComplexTypeModelDescription complexTypeDescription = null;
if (parameterDescriptor != null)
{
parameterType = parameterDescriptor.ParameterType;
typeDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
complexTypeDescription = typeDescription as ComplexTypeModelDescription;
}
// Example:
// [TypeConverter(typeof(PointConverter))]
// public class Point
// {
// public Point(int x, int y)
// {
// X = x;
// Y = y;
// }
// public int X { get; set; }
// public int Y { get; set; }
// }
// Class Point is bindable with a TypeConverter, so Point will be added to UriParameters collection.
//
// public class Point
// {
// public int X { get; set; }
// public int Y { get; set; }
// }
// Regular complex class Point will have properties X and Y added to UriParameters collection.
if (complexTypeDescription != null
&& !IsBindableWithTypeConverter(parameterType))
{
foreach (ParameterDescription uriParameter in complexTypeDescription.Properties)
{
apiModel.UriParameters.Add(uriParameter);
}
}
else if (parameterDescriptor != null)
{
ParameterDescription uriParameter =
AddParameterDescription(apiModel, apiParameter, typeDescription);
if (!parameterDescriptor.IsOptional)
{
uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Required" });
}
object defaultValue = parameterDescriptor.DefaultValue;
if (defaultValue != null)
{
uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Default value is " + Convert.ToString(defaultValue, CultureInfo.InvariantCulture) });
}
}
else
{
Debug.Assert(parameterDescriptor == null);
// If parameterDescriptor is null, this is an undeclared route parameter which only occurs
// when source is FromUri. Ignored in request model and among resource parameters but listed
// as a simple string here.
ModelDescription modelDescription = modelGenerator.GetOrCreateModelDescription(typeof(string));
AddParameterDescription(apiModel, apiParameter, modelDescription);
}
}
}
}
private static bool IsBindableWithTypeConverter(Type parameterType)
{
if (parameterType == null)
{
return false;
}
return TypeDescriptor.GetConverter(parameterType).CanConvertFrom(typeof(string));
}
private static ParameterDescription AddParameterDescription(HelpPageApiModel apiModel,
ApiParameterDescription apiParameter, ModelDescription typeDescription)
{
ParameterDescription parameterDescription = new ParameterDescription
{
Name = apiParameter.Name,
Documentation = apiParameter.Documentation,
TypeDescription = typeDescription,
};
apiModel.UriParameters.Add(parameterDescription);
return parameterDescription;
}
private static void GenerateRequestModelDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator, HelpPageSampleGenerator sampleGenerator)
{
ApiDescription apiDescription = apiModel.ApiDescription;
foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions)
{
if (apiParameter.Source == ApiParameterSource.FromBody)
{
Type parameterType = apiParameter.ParameterDescriptor.ParameterType;
apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
apiModel.RequestDocumentation = apiParameter.Documentation;
}
else if (apiParameter.ParameterDescriptor != null &&
apiParameter.ParameterDescriptor.ParameterType == typeof(HttpRequestMessage))
{
Type parameterType = sampleGenerator.ResolveHttpRequestMessageType(apiDescription);
if (parameterType != null)
{
apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
}
}
}
}
private static void GenerateResourceDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator)
{
ResponseDescription response = apiModel.ApiDescription.ResponseDescription;
Type responseType = response.ResponseType ?? response.DeclaredType;
if (responseType != null && responseType != typeof(void))
{
apiModel.ResourceDescription = modelGenerator.GetOrCreateModelDescription(responseType);
}
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as ErrorMessages.")]
private static void GenerateSamples(HelpPageApiModel apiModel, HelpPageSampleGenerator sampleGenerator)
{
try
{
foreach (var item in sampleGenerator.GetSampleRequests(apiModel.ApiDescription))
{
apiModel.SampleRequests.Add(item.Key, item.Value);
LogInvalidSampleAsError(apiModel, item.Value);
}
foreach (var item in sampleGenerator.GetSampleResponses(apiModel.ApiDescription))
{
apiModel.SampleResponses.Add(item.Key, item.Value);
LogInvalidSampleAsError(apiModel, item.Value);
}
}
catch (Exception e)
{
apiModel.ErrorMessages.Add(String.Format(CultureInfo.CurrentCulture,
"An exception has occurred while generating the sample. Exception message: {0}",
HelpPageSampleGenerator.UnwrapException(e).Message));
}
}
private static bool TryGetResourceParameter(ApiDescription apiDescription, HttpConfiguration config, out ApiParameterDescription parameterDescription, out Type resourceType)
{
parameterDescription = apiDescription.ParameterDescriptions.FirstOrDefault(
p => p.Source == ApiParameterSource.FromBody ||
(p.ParameterDescriptor != null && p.ParameterDescriptor.ParameterType == typeof(HttpRequestMessage)));
if (parameterDescription == null)
{
resourceType = null;
return false;
}
resourceType = parameterDescription.ParameterDescriptor.ParameterType;
if (resourceType == typeof(HttpRequestMessage))
{
HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
resourceType = sampleGenerator.ResolveHttpRequestMessageType(apiDescription);
}
if (resourceType == null)
{
parameterDescription = null;
return false;
}
return true;
}
private static ModelDescriptionGenerator InitializeModelDescriptionGenerator(HttpConfiguration config)
{
ModelDescriptionGenerator modelGenerator = new ModelDescriptionGenerator(config);
Collection<ApiDescription> apis = config.Services.GetApiExplorer().ApiDescriptions;
foreach (ApiDescription api in apis)
{
ApiParameterDescription parameterDescription;
Type parameterType;
if (TryGetResourceParameter(api, config, out parameterDescription, out parameterType))
{
modelGenerator.GetOrCreateModelDescription(parameterType);
}
}
return modelGenerator;
}
private static void LogInvalidSampleAsError(HelpPageApiModel apiModel, object sample)
{
InvalidSample invalidSample = sample as InvalidSample;
if (invalidSample != null)
{
apiModel.ErrorMessages.Add(invalidSample.ErrorMessage);
}
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class CollectionModelDescription : ModelDescription
{
public ModelDescription ElementDescription { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,14 @@
using System.Collections.ObjectModel;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class ComplexTypeModelDescription : ModelDescription
{
public ComplexTypeModelDescription()
{
Properties = new Collection<ParameterDescription>();
}
public Collection<ParameterDescription> Properties { get; private set; }
}
}

Просмотреть файл

@ -0,0 +1,6 @@
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class DictionaryModelDescription : KeyValuePairModelDescription
{
}
}

Просмотреть файл

@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class EnumTypeModelDescription : ModelDescription
{
public EnumTypeModelDescription()
{
Values = new Collection<EnumValueDescription>();
}
public Collection<EnumValueDescription> Values { get; private set; }
}
}

Просмотреть файл

@ -0,0 +1,11 @@
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class EnumValueDescription
{
public string Documentation { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,12 @@
using System;
using System.Reflection;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public interface IModelDocumentationProvider
{
string GetDocumentation(MemberInfo member);
string GetDocumentation(Type type);
}
}

Просмотреть файл

@ -0,0 +1,9 @@
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class KeyValuePairModelDescription : ModelDescription
{
public ModelDescription KeyModelDescription { get; set; }
public ModelDescription ValueModelDescription { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,16 @@
using System;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
/// <summary>
/// Describes a type model.
/// </summary>
public abstract class ModelDescription
{
public string Documentation { get; set; }
public Type ModelType { get; set; }
public string Name { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,451 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using System.Web.Http;
using System.Web.Http.Description;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
/// <summary>
/// Generates model descriptions for given types.
/// </summary>
public class ModelDescriptionGenerator
{
// Modify this to support more data annotation attributes.
private readonly IDictionary<Type, Func<object, string>> AnnotationTextGenerator = new Dictionary<Type, Func<object, string>>
{
{ typeof(RequiredAttribute), a => "Required" },
{ typeof(RangeAttribute), a =>
{
RangeAttribute range = (RangeAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Range: inclusive between {0} and {1}", range.Minimum, range.Maximum);
}
},
{ typeof(MaxLengthAttribute), a =>
{
MaxLengthAttribute maxLength = (MaxLengthAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Max length: {0}", maxLength.Length);
}
},
{ typeof(MinLengthAttribute), a =>
{
MinLengthAttribute minLength = (MinLengthAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Min length: {0}", minLength.Length);
}
},
{ typeof(StringLengthAttribute), a =>
{
StringLengthAttribute strLength = (StringLengthAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "String length: inclusive between {0} and {1}", strLength.MinimumLength, strLength.MaximumLength);
}
},
{ typeof(DataTypeAttribute), a =>
{
DataTypeAttribute dataType = (DataTypeAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Data type: {0}", dataType.CustomDataType ?? dataType.DataType.ToString());
}
},
{ typeof(RegularExpressionAttribute), a =>
{
RegularExpressionAttribute regularExpression = (RegularExpressionAttribute)a;
return String.Format(CultureInfo.CurrentCulture, "Matching regular expression pattern: {0}", regularExpression.Pattern);
}
},
};
// Modify this to add more default documentations.
private readonly IDictionary<Type, string> DefaultTypeDocumentation = new Dictionary<Type, string>
{
{ typeof(Int16), "integer" },
{ typeof(Int32), "integer" },
{ typeof(Int64), "integer" },
{ typeof(UInt16), "unsigned integer" },
{ typeof(UInt32), "unsigned integer" },
{ typeof(UInt64), "unsigned integer" },
{ typeof(Byte), "byte" },
{ typeof(Char), "character" },
{ typeof(SByte), "signed byte" },
{ typeof(Uri), "URI" },
{ typeof(Single), "decimal number" },
{ typeof(Double), "decimal number" },
{ typeof(Decimal), "decimal number" },
{ typeof(String), "string" },
{ typeof(Guid), "globally unique identifier" },
{ typeof(TimeSpan), "time interval" },
{ typeof(DateTime), "date" },
{ typeof(DateTimeOffset), "date" },
{ typeof(Boolean), "boolean" },
};
private Lazy<IModelDocumentationProvider> _documentationProvider;
public ModelDescriptionGenerator(HttpConfiguration config)
{
if (config == null)
{
throw new ArgumentNullException("config");
}
_documentationProvider = new Lazy<IModelDocumentationProvider>(() => config.Services.GetDocumentationProvider() as IModelDocumentationProvider);
GeneratedModels = new Dictionary<string, ModelDescription>(StringComparer.OrdinalIgnoreCase);
}
public Dictionary<string, ModelDescription> GeneratedModels { get; private set; }
private IModelDocumentationProvider DocumentationProvider
{
get
{
return _documentationProvider.Value;
}
}
public ModelDescription GetOrCreateModelDescription(Type modelType)
{
if (modelType == null)
{
throw new ArgumentNullException("modelType");
}
Type underlyingType = Nullable.GetUnderlyingType(modelType);
if (underlyingType != null)
{
modelType = underlyingType;
}
ModelDescription modelDescription;
string modelName = ModelNameHelper.GetModelName(modelType);
if (GeneratedModels.TryGetValue(modelName, out modelDescription))
{
if (modelType != modelDescription.ModelType)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
"A model description could not be created. Duplicate model name '{0}' was found for types '{1}' and '{2}'. " +
"Use the [ModelName] attribute to change the model name for at least one of the types so that it has a unique name.",
modelName,
modelDescription.ModelType.FullName,
modelType.FullName));
}
return modelDescription;
}
if (DefaultTypeDocumentation.ContainsKey(modelType))
{
return GenerateSimpleTypeModelDescription(modelType);
}
if (modelType.IsEnum)
{
return GenerateEnumTypeModelDescription(modelType);
}
if (modelType.IsGenericType)
{
Type[] genericArguments = modelType.GetGenericArguments();
if (genericArguments.Length == 1)
{
Type enumerableType = typeof(IEnumerable<>).MakeGenericType(genericArguments);
if (enumerableType.IsAssignableFrom(modelType))
{
return GenerateCollectionModelDescription(modelType, genericArguments[0]);
}
}
if (genericArguments.Length == 2)
{
Type dictionaryType = typeof(IDictionary<,>).MakeGenericType(genericArguments);
if (dictionaryType.IsAssignableFrom(modelType))
{
return GenerateDictionaryModelDescription(modelType, genericArguments[0], genericArguments[1]);
}
Type keyValuePairType = typeof(KeyValuePair<,>).MakeGenericType(genericArguments);
if (keyValuePairType.IsAssignableFrom(modelType))
{
return GenerateKeyValuePairModelDescription(modelType, genericArguments[0], genericArguments[1]);
}
}
}
if (modelType.IsArray)
{
Type elementType = modelType.GetElementType();
return GenerateCollectionModelDescription(modelType, elementType);
}
if (modelType == typeof(NameValueCollection))
{
return GenerateDictionaryModelDescription(modelType, typeof(string), typeof(string));
}
if (typeof(IDictionary).IsAssignableFrom(modelType))
{
return GenerateDictionaryModelDescription(modelType, typeof(object), typeof(object));
}
if (typeof(IEnumerable).IsAssignableFrom(modelType))
{
return GenerateCollectionModelDescription(modelType, typeof(object));
}
return GenerateComplexTypeModelDescription(modelType);
}
// Change this to provide different name for the member.
private static string GetMemberName(MemberInfo member, bool hasDataContractAttribute)
{
JsonPropertyAttribute jsonProperty = member.GetCustomAttribute<JsonPropertyAttribute>();
if (jsonProperty != null && !String.IsNullOrEmpty(jsonProperty.PropertyName))
{
return jsonProperty.PropertyName;
}
if (hasDataContractAttribute)
{
DataMemberAttribute dataMember = member.GetCustomAttribute<DataMemberAttribute>();
if (dataMember != null && !String.IsNullOrEmpty(dataMember.Name))
{
return dataMember.Name;
}
}
return member.Name;
}
private static bool ShouldDisplayMember(MemberInfo member, bool hasDataContractAttribute)
{
JsonIgnoreAttribute jsonIgnore = member.GetCustomAttribute<JsonIgnoreAttribute>();
XmlIgnoreAttribute xmlIgnore = member.GetCustomAttribute<XmlIgnoreAttribute>();
IgnoreDataMemberAttribute ignoreDataMember = member.GetCustomAttribute<IgnoreDataMemberAttribute>();
NonSerializedAttribute nonSerialized = member.GetCustomAttribute<NonSerializedAttribute>();
ApiExplorerSettingsAttribute apiExplorerSetting = member.GetCustomAttribute<ApiExplorerSettingsAttribute>();
bool hasMemberAttribute = member.DeclaringType.IsEnum ?
member.GetCustomAttribute<EnumMemberAttribute>() != null :
member.GetCustomAttribute<DataMemberAttribute>() != null;
// Display member only if all the followings are true:
// no JsonIgnoreAttribute
// no XmlIgnoreAttribute
// no IgnoreDataMemberAttribute
// no NonSerializedAttribute
// no ApiExplorerSettingsAttribute with IgnoreApi set to true
// no DataContractAttribute without DataMemberAttribute or EnumMemberAttribute
return jsonIgnore == null &&
xmlIgnore == null &&
ignoreDataMember == null &&
nonSerialized == null &&
(apiExplorerSetting == null || !apiExplorerSetting.IgnoreApi) &&
(!hasDataContractAttribute || hasMemberAttribute);
}
private string CreateDefaultDocumentation(Type type)
{
string documentation;
if (DefaultTypeDocumentation.TryGetValue(type, out documentation))
{
return documentation;
}
if (DocumentationProvider != null)
{
documentation = DocumentationProvider.GetDocumentation(type);
}
return documentation;
}
private void GenerateAnnotations(MemberInfo property, ParameterDescription propertyModel)
{
List<ParameterAnnotation> annotations = new List<ParameterAnnotation>();
IEnumerable<Attribute> attributes = property.GetCustomAttributes();
foreach (Attribute attribute in attributes)
{
Func<object, string> textGenerator;
if (AnnotationTextGenerator.TryGetValue(attribute.GetType(), out textGenerator))
{
annotations.Add(
new ParameterAnnotation
{
AnnotationAttribute = attribute,
Documentation = textGenerator(attribute)
});
}
}
// Rearrange the annotations
annotations.Sort((x, y) =>
{
// Special-case RequiredAttribute so that it shows up on top
if (x.AnnotationAttribute is RequiredAttribute)
{
return -1;
}
if (y.AnnotationAttribute is RequiredAttribute)
{
return 1;
}
// Sort the rest based on alphabetic order of the documentation
return String.Compare(x.Documentation, y.Documentation, StringComparison.OrdinalIgnoreCase);
});
foreach (ParameterAnnotation annotation in annotations)
{
propertyModel.Annotations.Add(annotation);
}
}
private CollectionModelDescription GenerateCollectionModelDescription(Type modelType, Type elementType)
{
ModelDescription collectionModelDescription = GetOrCreateModelDescription(elementType);
if (collectionModelDescription != null)
{
return new CollectionModelDescription
{
Name = ModelNameHelper.GetModelName(modelType),
ModelType = modelType,
ElementDescription = collectionModelDescription
};
}
return null;
}
private ModelDescription GenerateComplexTypeModelDescription(Type modelType)
{
ComplexTypeModelDescription complexModelDescription = new ComplexTypeModelDescription
{
Name = ModelNameHelper.GetModelName(modelType),
ModelType = modelType,
Documentation = CreateDefaultDocumentation(modelType)
};
GeneratedModels.Add(complexModelDescription.Name, complexModelDescription);
bool hasDataContractAttribute = modelType.GetCustomAttribute<DataContractAttribute>() != null;
PropertyInfo[] properties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo property in properties)
{
if (ShouldDisplayMember(property, hasDataContractAttribute))
{
ParameterDescription propertyModel = new ParameterDescription
{
Name = GetMemberName(property, hasDataContractAttribute)
};
if (DocumentationProvider != null)
{
propertyModel.Documentation = DocumentationProvider.GetDocumentation(property);
}
GenerateAnnotations(property, propertyModel);
complexModelDescription.Properties.Add(propertyModel);
propertyModel.TypeDescription = GetOrCreateModelDescription(property.PropertyType);
}
}
FieldInfo[] fields = modelType.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
if (ShouldDisplayMember(field, hasDataContractAttribute))
{
ParameterDescription propertyModel = new ParameterDescription
{
Name = GetMemberName(field, hasDataContractAttribute)
};
if (DocumentationProvider != null)
{
propertyModel.Documentation = DocumentationProvider.GetDocumentation(field);
}
complexModelDescription.Properties.Add(propertyModel);
propertyModel.TypeDescription = GetOrCreateModelDescription(field.FieldType);
}
}
return complexModelDescription;
}
private DictionaryModelDescription GenerateDictionaryModelDescription(Type modelType, Type keyType, Type valueType)
{
ModelDescription keyModelDescription = GetOrCreateModelDescription(keyType);
ModelDescription valueModelDescription = GetOrCreateModelDescription(valueType);
return new DictionaryModelDescription
{
Name = ModelNameHelper.GetModelName(modelType),
ModelType = modelType,
KeyModelDescription = keyModelDescription,
ValueModelDescription = valueModelDescription
};
}
private EnumTypeModelDescription GenerateEnumTypeModelDescription(Type modelType)
{
EnumTypeModelDescription enumDescription = new EnumTypeModelDescription
{
Name = ModelNameHelper.GetModelName(modelType),
ModelType = modelType,
Documentation = CreateDefaultDocumentation(modelType)
};
bool hasDataContractAttribute = modelType.GetCustomAttribute<DataContractAttribute>() != null;
foreach (FieldInfo field in modelType.GetFields(BindingFlags.Public | BindingFlags.Static))
{
if (ShouldDisplayMember(field, hasDataContractAttribute))
{
EnumValueDescription enumValue = new EnumValueDescription
{
Name = field.Name,
Value = field.GetRawConstantValue().ToString()
};
if (DocumentationProvider != null)
{
enumValue.Documentation = DocumentationProvider.GetDocumentation(field);
}
enumDescription.Values.Add(enumValue);
}
}
GeneratedModels.Add(enumDescription.Name, enumDescription);
return enumDescription;
}
private KeyValuePairModelDescription GenerateKeyValuePairModelDescription(Type modelType, Type keyType, Type valueType)
{
ModelDescription keyModelDescription = GetOrCreateModelDescription(keyType);
ModelDescription valueModelDescription = GetOrCreateModelDescription(valueType);
return new KeyValuePairModelDescription
{
Name = ModelNameHelper.GetModelName(modelType),
ModelType = modelType,
KeyModelDescription = keyModelDescription,
ValueModelDescription = valueModelDescription
};
}
private ModelDescription GenerateSimpleTypeModelDescription(Type modelType)
{
SimpleTypeModelDescription simpleModelDescription = new SimpleTypeModelDescription
{
Name = ModelNameHelper.GetModelName(modelType),
ModelType = modelType,
Documentation = CreateDefaultDocumentation(modelType)
};
GeneratedModels.Add(simpleModelDescription.Name, simpleModelDescription);
return simpleModelDescription;
}
}
}

Просмотреть файл

@ -0,0 +1,18 @@
using System;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
/// <summary>
/// Use this attribute to change the name of the <see cref="ModelDescription"/> generated for a type.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = false, Inherited = false)]
public sealed class ModelNameAttribute : Attribute
{
public ModelNameAttribute(string name)
{
Name = name;
}
public string Name { get; private set; }
}
}

Просмотреть файл

@ -0,0 +1,36 @@
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
internal static class ModelNameHelper
{
// Modify this to provide custom model name mapping.
public static string GetModelName(Type type)
{
ModelNameAttribute modelNameAttribute = type.GetCustomAttribute<ModelNameAttribute>();
if (modelNameAttribute != null && !String.IsNullOrEmpty(modelNameAttribute.Name))
{
return modelNameAttribute.Name;
}
string modelName = type.Name;
if (type.IsGenericType)
{
// Format the generic type name to something like: GenericOfAgurment1AndArgument2
Type genericType = type.GetGenericTypeDefinition();
Type[] genericArguments = type.GetGenericArguments();
string genericTypeName = genericType.Name;
// Trim the generic parameter counts from the name
genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));
string[] argumentTypeNames = genericArguments.Select(t => GetModelName(t)).ToArray();
modelName = String.Format(CultureInfo.InvariantCulture, "{0}Of{1}", genericTypeName, String.Join("And", argumentTypeNames));
}
return modelName;
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
using System;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class ParameterAnnotation
{
public Attribute AnnotationAttribute { get; set; }
public string Documentation { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class ParameterDescription
{
public ParameterDescription()
{
Annotations = new Collection<ParameterAnnotation>();
}
public Collection<ParameterAnnotation> Annotations { get; private set; }
public string Documentation { get; set; }
public string Name { get; set; }
public ModelDescription TypeDescription { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,6 @@
namespace InsuranceAPI.Areas.HelpPage.ModelDescriptions
{
public class SimpleTypeModelDescription : ModelDescription
{
}
}

Просмотреть файл

@ -0,0 +1,108 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net.Http.Headers;
using System.Web.Http.Description;
using InsuranceAPI.Areas.HelpPage.ModelDescriptions;
namespace InsuranceAPI.Areas.HelpPage.Models
{
/// <summary>
/// The model that represents an API displayed on the help page.
/// </summary>
public class HelpPageApiModel
{
/// <summary>
/// Initializes a new instance of the <see cref="HelpPageApiModel"/> class.
/// </summary>
public HelpPageApiModel()
{
UriParameters = new Collection<ParameterDescription>();
SampleRequests = new Dictionary<MediaTypeHeaderValue, object>();
SampleResponses = new Dictionary<MediaTypeHeaderValue, object>();
ErrorMessages = new Collection<string>();
}
/// <summary>
/// Gets or sets the <see cref="ApiDescription"/> that describes the API.
/// </summary>
public ApiDescription ApiDescription { get; set; }
/// <summary>
/// Gets or sets the <see cref="ParameterDescription"/> collection that describes the URI parameters for the API.
/// </summary>
public Collection<ParameterDescription> UriParameters { get; private set; }
/// <summary>
/// Gets or sets the documentation for the request.
/// </summary>
public string RequestDocumentation { get; set; }
/// <summary>
/// Gets or sets the <see cref="ModelDescription"/> that describes the request body.
/// </summary>
public ModelDescription RequestModelDescription { get; set; }
/// <summary>
/// Gets the request body parameter descriptions.
/// </summary>
public IList<ParameterDescription> RequestBodyParameters
{
get
{
return GetParameterDescriptions(RequestModelDescription);
}
}
/// <summary>
/// Gets or sets the <see cref="ModelDescription"/> that describes the resource.
/// </summary>
public ModelDescription ResourceDescription { get; set; }
/// <summary>
/// Gets the resource property descriptions.
/// </summary>
public IList<ParameterDescription> ResourceProperties
{
get
{
return GetParameterDescriptions(ResourceDescription);
}
}
/// <summary>
/// Gets the sample requests associated with the API.
/// </summary>
public IDictionary<MediaTypeHeaderValue, object> SampleRequests { get; private set; }
/// <summary>
/// Gets the sample responses associated with the API.
/// </summary>
public IDictionary<MediaTypeHeaderValue, object> SampleResponses { get; private set; }
/// <summary>
/// Gets the error messages associated with this model.
/// </summary>
public Collection<string> ErrorMessages { get; private set; }
private static IList<ParameterDescription> GetParameterDescriptions(ModelDescription modelDescription)
{
ComplexTypeModelDescription complexTypeModelDescription = modelDescription as ComplexTypeModelDescription;
if (complexTypeModelDescription != null)
{
return complexTypeModelDescription.Properties;
}
CollectionModelDescription collectionModelDescription = modelDescription as CollectionModelDescription;
if (collectionModelDescription != null)
{
complexTypeModelDescription = collectionModelDescription.ElementDescription as ComplexTypeModelDescription;
if (complexTypeModelDescription != null)
{
return complexTypeModelDescription.Properties;
}
}
return null;
}
}
}

Просмотреть файл

@ -0,0 +1,444 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web.Http.Description;
using System.Xml.Linq;
using Newtonsoft.Json;
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// This class will generate the samples for the help page.
/// </summary>
public class HelpPageSampleGenerator
{
/// <summary>
/// Initializes a new instance of the <see cref="HelpPageSampleGenerator"/> class.
/// </summary>
public HelpPageSampleGenerator()
{
ActualHttpMessageTypes = new Dictionary<HelpPageSampleKey, Type>();
ActionSamples = new Dictionary<HelpPageSampleKey, object>();
SampleObjects = new Dictionary<Type, object>();
SampleObjectFactories = new List<Func<HelpPageSampleGenerator, Type, object>>
{
DefaultSampleObjectFactory,
};
}
/// <summary>
/// Gets CLR types that are used as the content of <see cref="HttpRequestMessage"/> or <see cref="HttpResponseMessage"/>.
/// </summary>
public IDictionary<HelpPageSampleKey, Type> ActualHttpMessageTypes { get; internal set; }
/// <summary>
/// Gets the objects that are used directly as samples for certain actions.
/// </summary>
public IDictionary<HelpPageSampleKey, object> ActionSamples { get; internal set; }
/// <summary>
/// Gets the objects that are serialized as samples by the supported formatters.
/// </summary>
public IDictionary<Type, object> SampleObjects { get; internal set; }
/// <summary>
/// Gets factories for the objects that the supported formatters will serialize as samples. Processed in order,
/// stopping when the factory successfully returns a non-<see langref="null"/> object.
/// </summary>
/// <remarks>
/// Collection includes just <see cref="ObjectGenerator.GenerateObject(Type)"/> initially. Use
/// <code>SampleObjectFactories.Insert(0, func)</code> to provide an override and
/// <code>SampleObjectFactories.Add(func)</code> to provide a fallback.</remarks>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
Justification = "This is an appropriate nesting of generic types")]
public IList<Func<HelpPageSampleGenerator, Type, object>> SampleObjectFactories { get; private set; }
/// <summary>
/// Gets the request body samples for a given <see cref="ApiDescription"/>.
/// </summary>
/// <param name="api">The <see cref="ApiDescription"/>.</param>
/// <returns>The samples keyed by media type.</returns>
public IDictionary<MediaTypeHeaderValue, object> GetSampleRequests(ApiDescription api)
{
return GetSample(api, SampleDirection.Request);
}
/// <summary>
/// Gets the response body samples for a given <see cref="ApiDescription"/>.
/// </summary>
/// <param name="api">The <see cref="ApiDescription"/>.</param>
/// <returns>The samples keyed by media type.</returns>
public IDictionary<MediaTypeHeaderValue, object> GetSampleResponses(ApiDescription api)
{
return GetSample(api, SampleDirection.Response);
}
/// <summary>
/// Gets the request or response body samples.
/// </summary>
/// <param name="api">The <see cref="ApiDescription"/>.</param>
/// <param name="sampleDirection">The value indicating whether the sample is for a request or for a response.</param>
/// <returns>The samples keyed by media type.</returns>
public virtual IDictionary<MediaTypeHeaderValue, object> GetSample(ApiDescription api, SampleDirection sampleDirection)
{
if (api == null)
{
throw new ArgumentNullException("api");
}
string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName;
string actionName = api.ActionDescriptor.ActionName;
IEnumerable<string> parameterNames = api.ParameterDescriptions.Select(p => p.Name);
Collection<MediaTypeFormatter> formatters;
Type type = ResolveType(api, controllerName, actionName, parameterNames, sampleDirection, out formatters);
var samples = new Dictionary<MediaTypeHeaderValue, object>();
// Use the samples provided directly for actions
var actionSamples = GetAllActionSamples(controllerName, actionName, parameterNames, sampleDirection);
foreach (var actionSample in actionSamples)
{
samples.Add(actionSample.Key.MediaType, WrapSampleIfString(actionSample.Value));
}
// Do the sample generation based on formatters only if an action doesn't return an HttpResponseMessage.
// Here we cannot rely on formatters because we don't know what's in the HttpResponseMessage, it might not even use formatters.
if (type != null && !typeof(HttpResponseMessage).IsAssignableFrom(type))
{
object sampleObject = GetSampleObject(type);
foreach (var formatter in formatters)
{
foreach (MediaTypeHeaderValue mediaType in formatter.SupportedMediaTypes)
{
if (!samples.ContainsKey(mediaType))
{
object sample = GetActionSample(controllerName, actionName, parameterNames, type, formatter, mediaType, sampleDirection);
// If no sample found, try generate sample using formatter and sample object
if (sample == null && sampleObject != null)
{
sample = WriteSampleObjectUsingFormatter(formatter, sampleObject, type, mediaType);
}
samples.Add(mediaType, WrapSampleIfString(sample));
}
}
}
}
return samples;
}
/// <summary>
/// Search for samples that are provided directly through <see cref="ActionSamples"/>.
/// </summary>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
/// <param name="type">The CLR type.</param>
/// <param name="formatter">The formatter.</param>
/// <param name="mediaType">The media type.</param>
/// <param name="sampleDirection">The value indicating whether the sample is for a request or for a response.</param>
/// <returns>The sample that matches the parameters.</returns>
public virtual object GetActionSample(string controllerName, string actionName, IEnumerable<string> parameterNames, Type type, MediaTypeFormatter formatter, MediaTypeHeaderValue mediaType, SampleDirection sampleDirection)
{
object sample;
// First, try to get the sample provided for the specified mediaType, sampleDirection, controllerName, actionName and parameterNames.
// If not found, try to get the sample provided for the specified mediaType, sampleDirection, controllerName and actionName regardless of the parameterNames.
// If still not found, try to get the sample provided for the specified mediaType and type.
// Finally, try to get the sample provided for the specified mediaType.
if (ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, sampleDirection, controllerName, actionName, parameterNames), out sample) ||
ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, sampleDirection, controllerName, actionName, new[] { "*" }), out sample) ||
ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType, type), out sample) ||
ActionSamples.TryGetValue(new HelpPageSampleKey(mediaType), out sample))
{
return sample;
}
return null;
}
/// <summary>
/// Gets the sample object that will be serialized by the formatters.
/// First, it will look at the <see cref="SampleObjects"/>. If no sample object is found, it will try to create
/// one using <see cref="DefaultSampleObjectFactory"/> (which wraps an <see cref="ObjectGenerator"/>) and other
/// factories in <see cref="SampleObjectFactories"/>.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>The sample object.</returns>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
Justification = "Even if all items in SampleObjectFactories throw, problem will be visible as missing sample.")]
public virtual object GetSampleObject(Type type)
{
object sampleObject;
if (!SampleObjects.TryGetValue(type, out sampleObject))
{
// No specific object available, try our factories.
foreach (Func<HelpPageSampleGenerator, Type, object> factory in SampleObjectFactories)
{
if (factory == null)
{
continue;
}
try
{
sampleObject = factory(this, type);
if (sampleObject != null)
{
break;
}
}
catch
{
// Ignore any problems encountered in the factory; go on to the next one (if any).
}
}
}
return sampleObject;
}
/// <summary>
/// Resolves the actual type of <see cref="System.Net.Http.ObjectContent{T}"/> passed to the <see cref="System.Net.Http.HttpRequestMessage"/> in an action.
/// </summary>
/// <param name="api">The <see cref="ApiDescription"/>.</param>
/// <returns>The type.</returns>
public virtual Type ResolveHttpRequestMessageType(ApiDescription api)
{
string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName;
string actionName = api.ActionDescriptor.ActionName;
IEnumerable<string> parameterNames = api.ParameterDescriptions.Select(p => p.Name);
Collection<MediaTypeFormatter> formatters;
return ResolveType(api, controllerName, actionName, parameterNames, SampleDirection.Request, out formatters);
}
/// <summary>
/// Resolves the type of the action parameter or return value when <see cref="HttpRequestMessage"/> or <see cref="HttpResponseMessage"/> is used.
/// </summary>
/// <param name="api">The <see cref="ApiDescription"/>.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
/// <param name="sampleDirection">The value indicating whether the sample is for a request or a response.</param>
/// <param name="formatters">The formatters.</param>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", Justification = "This is only used in advanced scenarios.")]
public virtual Type ResolveType(ApiDescription api, string controllerName, string actionName, IEnumerable<string> parameterNames, SampleDirection sampleDirection, out Collection<MediaTypeFormatter> formatters)
{
if (!Enum.IsDefined(typeof(SampleDirection), sampleDirection))
{
throw new InvalidEnumArgumentException("sampleDirection", (int)sampleDirection, typeof(SampleDirection));
}
if (api == null)
{
throw new ArgumentNullException("api");
}
Type type;
if (ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, parameterNames), out type) ||
ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, new[] { "*" }), out type))
{
// Re-compute the supported formatters based on type
Collection<MediaTypeFormatter> newFormatters = new Collection<MediaTypeFormatter>();
foreach (var formatter in api.ActionDescriptor.Configuration.Formatters)
{
if (IsFormatSupported(sampleDirection, formatter, type))
{
newFormatters.Add(formatter);
}
}
formatters = newFormatters;
}
else
{
switch (sampleDirection)
{
case SampleDirection.Request:
ApiParameterDescription requestBodyParameter = api.ParameterDescriptions.FirstOrDefault(p => p.Source == ApiParameterSource.FromBody);
type = requestBodyParameter == null ? null : requestBodyParameter.ParameterDescriptor.ParameterType;
formatters = api.SupportedRequestBodyFormatters;
break;
case SampleDirection.Response:
default:
type = api.ResponseDescription.ResponseType ?? api.ResponseDescription.DeclaredType;
formatters = api.SupportedResponseFormatters;
break;
}
}
return type;
}
/// <summary>
/// Writes the sample object using formatter.
/// </summary>
/// <param name="formatter">The formatter.</param>
/// <param name="value">The value.</param>
/// <param name="type">The type.</param>
/// <param name="mediaType">Type of the media.</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as InvalidSample.")]
public virtual object WriteSampleObjectUsingFormatter(MediaTypeFormatter formatter, object value, Type type, MediaTypeHeaderValue mediaType)
{
if (formatter == null)
{
throw new ArgumentNullException("formatter");
}
if (mediaType == null)
{
throw new ArgumentNullException("mediaType");
}
object sample = String.Empty;
MemoryStream ms = null;
HttpContent content = null;
try
{
if (formatter.CanWriteType(type))
{
ms = new MemoryStream();
content = new ObjectContent(type, value, formatter, mediaType);
formatter.WriteToStreamAsync(type, value, ms, content, null).Wait();
ms.Position = 0;
StreamReader reader = new StreamReader(ms);
string serializedSampleString = reader.ReadToEnd();
if (mediaType.MediaType.ToUpperInvariant().Contains("XML"))
{
serializedSampleString = TryFormatXml(serializedSampleString);
}
else if (mediaType.MediaType.ToUpperInvariant().Contains("JSON"))
{
serializedSampleString = TryFormatJson(serializedSampleString);
}
sample = new TextSample(serializedSampleString);
}
else
{
sample = new InvalidSample(String.Format(
CultureInfo.CurrentCulture,
"Failed to generate the sample for media type '{0}'. Cannot use formatter '{1}' to write type '{2}'.",
mediaType,
formatter.GetType().Name,
type.Name));
}
}
catch (Exception e)
{
sample = new InvalidSample(String.Format(
CultureInfo.CurrentCulture,
"An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}",
formatter.GetType().Name,
mediaType.MediaType,
UnwrapException(e).Message));
}
finally
{
if (ms != null)
{
ms.Dispose();
}
if (content != null)
{
content.Dispose();
}
}
return sample;
}
internal static Exception UnwrapException(Exception exception)
{
AggregateException aggregateException = exception as AggregateException;
if (aggregateException != null)
{
return aggregateException.Flatten().InnerException;
}
return exception;
}
// Default factory for sample objects
private static object DefaultSampleObjectFactory(HelpPageSampleGenerator sampleGenerator, Type type)
{
// Try to create a default sample object
ObjectGenerator objectGenerator = new ObjectGenerator();
return objectGenerator.GenerateObject(type);
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Handling the failure by returning the original string.")]
private static string TryFormatJson(string str)
{
try
{
object parsedJson = JsonConvert.DeserializeObject(str);
return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
}
catch
{
// can't parse JSON, return the original string
return str;
}
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Handling the failure by returning the original string.")]
private static string TryFormatXml(string str)
{
try
{
XDocument xml = XDocument.Parse(str);
return xml.ToString();
}
catch
{
// can't parse XML, return the original string
return str;
}
}
private static bool IsFormatSupported(SampleDirection sampleDirection, MediaTypeFormatter formatter, Type type)
{
switch (sampleDirection)
{
case SampleDirection.Request:
return formatter.CanReadType(type);
case SampleDirection.Response:
return formatter.CanWriteType(type);
}
return false;
}
private IEnumerable<KeyValuePair<HelpPageSampleKey, object>> GetAllActionSamples(string controllerName, string actionName, IEnumerable<string> parameterNames, SampleDirection sampleDirection)
{
HashSet<string> parameterNamesSet = new HashSet<string>(parameterNames, StringComparer.OrdinalIgnoreCase);
foreach (var sample in ActionSamples)
{
HelpPageSampleKey sampleKey = sample.Key;
if (String.Equals(controllerName, sampleKey.ControllerName, StringComparison.OrdinalIgnoreCase) &&
String.Equals(actionName, sampleKey.ActionName, StringComparison.OrdinalIgnoreCase) &&
(sampleKey.ParameterNames.SetEquals(new[] { "*" }) || parameterNamesSet.SetEquals(sampleKey.ParameterNames)) &&
sampleDirection == sampleKey.SampleDirection)
{
yield return sample;
}
}
}
private static object WrapSampleIfString(object sample)
{
string stringSample = sample as string;
if (stringSample != null)
{
return new TextSample(stringSample);
}
return sample;
}
}
}

Просмотреть файл

@ -0,0 +1,172 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http.Headers;
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// This is used to identify the place where the sample should be applied.
/// </summary>
public class HelpPageSampleKey
{
/// <summary>
/// Creates a new <see cref="HelpPageSampleKey"/> based on media type.
/// </summary>
/// <param name="mediaType">The media type.</param>
public HelpPageSampleKey(MediaTypeHeaderValue mediaType)
{
if (mediaType == null)
{
throw new ArgumentNullException("mediaType");
}
ActionName = String.Empty;
ControllerName = String.Empty;
MediaType = mediaType;
ParameterNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Creates a new <see cref="HelpPageSampleKey"/> based on media type and CLR type.
/// </summary>
/// <param name="mediaType">The media type.</param>
/// <param name="type">The CLR type.</param>
public HelpPageSampleKey(MediaTypeHeaderValue mediaType, Type type)
: this(mediaType)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
ParameterType = type;
}
/// <summary>
/// Creates a new <see cref="HelpPageSampleKey"/> based on <see cref="SampleDirection"/>, controller name, action name and parameter names.
/// </summary>
/// <param name="sampleDirection">The <see cref="SampleDirection"/>.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
public HelpPageSampleKey(SampleDirection sampleDirection, string controllerName, string actionName, IEnumerable<string> parameterNames)
{
if (!Enum.IsDefined(typeof(SampleDirection), sampleDirection))
{
throw new InvalidEnumArgumentException("sampleDirection", (int)sampleDirection, typeof(SampleDirection));
}
if (controllerName == null)
{
throw new ArgumentNullException("controllerName");
}
if (actionName == null)
{
throw new ArgumentNullException("actionName");
}
if (parameterNames == null)
{
throw new ArgumentNullException("parameterNames");
}
ControllerName = controllerName;
ActionName = actionName;
ParameterNames = new HashSet<string>(parameterNames, StringComparer.OrdinalIgnoreCase);
SampleDirection = sampleDirection;
}
/// <summary>
/// Creates a new <see cref="HelpPageSampleKey"/> based on media type, <see cref="SampleDirection"/>, controller name, action name and parameter names.
/// </summary>
/// <param name="mediaType">The media type.</param>
/// <param name="sampleDirection">The <see cref="SampleDirection"/>.</param>
/// <param name="controllerName">Name of the controller.</param>
/// <param name="actionName">Name of the action.</param>
/// <param name="parameterNames">The parameter names.</param>
public HelpPageSampleKey(MediaTypeHeaderValue mediaType, SampleDirection sampleDirection, string controllerName, string actionName, IEnumerable<string> parameterNames)
: this(sampleDirection, controllerName, actionName, parameterNames)
{
if (mediaType == null)
{
throw new ArgumentNullException("mediaType");
}
MediaType = mediaType;
}
/// <summary>
/// Gets the name of the controller.
/// </summary>
/// <value>
/// The name of the controller.
/// </value>
public string ControllerName { get; private set; }
/// <summary>
/// Gets the name of the action.
/// </summary>
/// <value>
/// The name of the action.
/// </value>
public string ActionName { get; private set; }
/// <summary>
/// Gets the media type.
/// </summary>
/// <value>
/// The media type.
/// </value>
public MediaTypeHeaderValue MediaType { get; private set; }
/// <summary>
/// Gets the parameter names.
/// </summary>
public HashSet<string> ParameterNames { get; private set; }
public Type ParameterType { get; private set; }
/// <summary>
/// Gets the <see cref="SampleDirection"/>.
/// </summary>
public SampleDirection? SampleDirection { get; private set; }
public override bool Equals(object obj)
{
HelpPageSampleKey otherKey = obj as HelpPageSampleKey;
if (otherKey == null)
{
return false;
}
return String.Equals(ControllerName, otherKey.ControllerName, StringComparison.OrdinalIgnoreCase) &&
String.Equals(ActionName, otherKey.ActionName, StringComparison.OrdinalIgnoreCase) &&
(MediaType == otherKey.MediaType || (MediaType != null && MediaType.Equals(otherKey.MediaType))) &&
ParameterType == otherKey.ParameterType &&
SampleDirection == otherKey.SampleDirection &&
ParameterNames.SetEquals(otherKey.ParameterNames);
}
public override int GetHashCode()
{
int hashCode = ControllerName.ToUpperInvariant().GetHashCode() ^ ActionName.ToUpperInvariant().GetHashCode();
if (MediaType != null)
{
hashCode ^= MediaType.GetHashCode();
}
if (SampleDirection != null)
{
hashCode ^= SampleDirection.GetHashCode();
}
if (ParameterType != null)
{
hashCode ^= ParameterType.GetHashCode();
}
foreach (string parameterName in ParameterNames)
{
hashCode ^= parameterName.ToUpperInvariant().GetHashCode();
}
return hashCode;
}
}
}

Просмотреть файл

@ -0,0 +1,41 @@
using System;
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// This represents an image sample on the help page. There's a display template named ImageSample associated with this class.
/// </summary>
public class ImageSample
{
/// <summary>
/// Initializes a new instance of the <see cref="ImageSample"/> class.
/// </summary>
/// <param name="src">The URL of an image.</param>
public ImageSample(string src)
{
if (src == null)
{
throw new ArgumentNullException("src");
}
Src = src;
}
public string Src { get; private set; }
public override bool Equals(object obj)
{
ImageSample other = obj as ImageSample;
return other != null && Src == other.Src;
}
public override int GetHashCode()
{
return Src.GetHashCode();
}
public override string ToString()
{
return Src;
}
}
}

Просмотреть файл

@ -0,0 +1,37 @@
using System;
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// This represents an invalid sample on the help page. There's a display template named InvalidSample associated with this class.
/// </summary>
public class InvalidSample
{
public InvalidSample(string errorMessage)
{
if (errorMessage == null)
{
throw new ArgumentNullException("errorMessage");
}
ErrorMessage = errorMessage;
}
public string ErrorMessage { get; private set; }
public override bool Equals(object obj)
{
InvalidSample other = obj as InvalidSample;
return other != null && ErrorMessage == other.ErrorMessage;
}
public override int GetHashCode()
{
return ErrorMessage.GetHashCode();
}
public override string ToString()
{
return ErrorMessage;
}
}
}

Просмотреть файл

@ -0,0 +1,456 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// This class will create an object of a given type and populate it with sample data.
/// </summary>
public class ObjectGenerator
{
internal const int DefaultCollectionSize = 2;
private readonly SimpleTypeObjectGenerator SimpleObjectGenerator = new SimpleTypeObjectGenerator();
/// <summary>
/// Generates an object for a given type. The type needs to be public, have a public default constructor and settable public properties/fields. Currently it supports the following types:
/// Simple types: <see cref="int"/>, <see cref="string"/>, <see cref="Enum"/>, <see cref="DateTime"/>, <see cref="Uri"/>, etc.
/// Complex types: POCO types.
/// Nullables: <see cref="Nullable{T}"/>.
/// Arrays: arrays of simple types or complex types.
/// Key value pairs: <see cref="KeyValuePair{TKey,TValue}"/>
/// Tuples: <see cref="Tuple{T1}"/>, <see cref="Tuple{T1,T2}"/>, etc
/// Dictionaries: <see cref="IDictionary{TKey,TValue}"/> or anything deriving from <see cref="IDictionary{TKey,TValue}"/>.
/// Collections: <see cref="IList{T}"/>, <see cref="IEnumerable{T}"/>, <see cref="ICollection{T}"/>, <see cref="IList"/>, <see cref="IEnumerable"/>, <see cref="ICollection"/> or anything deriving from <see cref="ICollection{T}"/> or <see cref="IList"/>.
/// Queryables: <see cref="IQueryable"/>, <see cref="IQueryable{T}"/>.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>An object of the given type.</returns>
public object GenerateObject(Type type)
{
return GenerateObject(type, new Dictionary<Type, object>());
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Here we just want to return null if anything goes wrong.")]
private object GenerateObject(Type type, Dictionary<Type, object> createdObjectReferences)
{
try
{
if (SimpleTypeObjectGenerator.CanGenerateObject(type))
{
return SimpleObjectGenerator.GenerateObject(type);
}
if (type.IsArray)
{
return GenerateArray(type, DefaultCollectionSize, createdObjectReferences);
}
if (type.IsGenericType)
{
return GenerateGenericType(type, DefaultCollectionSize, createdObjectReferences);
}
if (type == typeof(IDictionary))
{
return GenerateDictionary(typeof(Hashtable), DefaultCollectionSize, createdObjectReferences);
}
if (typeof(IDictionary).IsAssignableFrom(type))
{
return GenerateDictionary(type, DefaultCollectionSize, createdObjectReferences);
}
if (type == typeof(IList) ||
type == typeof(IEnumerable) ||
type == typeof(ICollection))
{
return GenerateCollection(typeof(ArrayList), DefaultCollectionSize, createdObjectReferences);
}
if (typeof(IList).IsAssignableFrom(type))
{
return GenerateCollection(type, DefaultCollectionSize, createdObjectReferences);
}
if (type == typeof(IQueryable))
{
return GenerateQueryable(type, DefaultCollectionSize, createdObjectReferences);
}
if (type.IsEnum)
{
return GenerateEnum(type);
}
if (type.IsPublic || type.IsNestedPublic)
{
return GenerateComplexObject(type, createdObjectReferences);
}
}
catch
{
// Returns null if anything fails
return null;
}
return null;
}
private static object GenerateGenericType(Type type, int collectionSize, Dictionary<Type, object> createdObjectReferences)
{
Type genericTypeDefinition = type.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Nullable<>))
{
return GenerateNullable(type, createdObjectReferences);
}
if (genericTypeDefinition == typeof(KeyValuePair<,>))
{
return GenerateKeyValuePair(type, createdObjectReferences);
}
if (IsTuple(genericTypeDefinition))
{
return GenerateTuple(type, createdObjectReferences);
}
Type[] genericArguments = type.GetGenericArguments();
if (genericArguments.Length == 1)
{
if (genericTypeDefinition == typeof(IList<>) ||
genericTypeDefinition == typeof(IEnumerable<>) ||
genericTypeDefinition == typeof(ICollection<>))
{
Type collectionType = typeof(List<>).MakeGenericType(genericArguments);
return GenerateCollection(collectionType, collectionSize, createdObjectReferences);
}
if (genericTypeDefinition == typeof(IQueryable<>))
{
return GenerateQueryable(type, collectionSize, createdObjectReferences);
}
Type closedCollectionType = typeof(ICollection<>).MakeGenericType(genericArguments[0]);
if (closedCollectionType.IsAssignableFrom(type))
{
return GenerateCollection(type, collectionSize, createdObjectReferences);
}
}
if (genericArguments.Length == 2)
{
if (genericTypeDefinition == typeof(IDictionary<,>))
{
Type dictionaryType = typeof(Dictionary<,>).MakeGenericType(genericArguments);
return GenerateDictionary(dictionaryType, collectionSize, createdObjectReferences);
}
Type closedDictionaryType = typeof(IDictionary<,>).MakeGenericType(genericArguments[0], genericArguments[1]);
if (closedDictionaryType.IsAssignableFrom(type))
{
return GenerateDictionary(type, collectionSize, createdObjectReferences);
}
}
if (type.IsPublic || type.IsNestedPublic)
{
return GenerateComplexObject(type, createdObjectReferences);
}
return null;
}
private static object GenerateTuple(Type type, Dictionary<Type, object> createdObjectReferences)
{
Type[] genericArgs = type.GetGenericArguments();
object[] parameterValues = new object[genericArgs.Length];
bool failedToCreateTuple = true;
ObjectGenerator objectGenerator = new ObjectGenerator();
for (int i = 0; i < genericArgs.Length; i++)
{
parameterValues[i] = objectGenerator.GenerateObject(genericArgs[i], createdObjectReferences);
failedToCreateTuple &= parameterValues[i] == null;
}
if (failedToCreateTuple)
{
return null;
}
object result = Activator.CreateInstance(type, parameterValues);
return result;
}
private static bool IsTuple(Type genericTypeDefinition)
{
return genericTypeDefinition == typeof(Tuple<>) ||
genericTypeDefinition == typeof(Tuple<,>) ||
genericTypeDefinition == typeof(Tuple<,,>) ||
genericTypeDefinition == typeof(Tuple<,,,>) ||
genericTypeDefinition == typeof(Tuple<,,,,>) ||
genericTypeDefinition == typeof(Tuple<,,,,,>) ||
genericTypeDefinition == typeof(Tuple<,,,,,,>) ||
genericTypeDefinition == typeof(Tuple<,,,,,,,>);
}
private static object GenerateKeyValuePair(Type keyValuePairType, Dictionary<Type, object> createdObjectReferences)
{
Type[] genericArgs = keyValuePairType.GetGenericArguments();
Type typeK = genericArgs[0];
Type typeV = genericArgs[1];
ObjectGenerator objectGenerator = new ObjectGenerator();
object keyObject = objectGenerator.GenerateObject(typeK, createdObjectReferences);
object valueObject = objectGenerator.GenerateObject(typeV, createdObjectReferences);
if (keyObject == null && valueObject == null)
{
// Failed to create key and values
return null;
}
object result = Activator.CreateInstance(keyValuePairType, keyObject, valueObject);
return result;
}
private static object GenerateArray(Type arrayType, int size, Dictionary<Type, object> createdObjectReferences)
{
Type type = arrayType.GetElementType();
Array result = Array.CreateInstance(type, size);
bool areAllElementsNull = true;
ObjectGenerator objectGenerator = new ObjectGenerator();
for (int i = 0; i < size; i++)
{
object element = objectGenerator.GenerateObject(type, createdObjectReferences);
result.SetValue(element, i);
areAllElementsNull &= element == null;
}
if (areAllElementsNull)
{
return null;
}
return result;
}
private static object GenerateDictionary(Type dictionaryType, int size, Dictionary<Type, object> createdObjectReferences)
{
Type typeK = typeof(object);
Type typeV = typeof(object);
if (dictionaryType.IsGenericType)
{
Type[] genericArgs = dictionaryType.GetGenericArguments();
typeK = genericArgs[0];
typeV = genericArgs[1];
}
object result = Activator.CreateInstance(dictionaryType);
MethodInfo addMethod = dictionaryType.GetMethod("Add") ?? dictionaryType.GetMethod("TryAdd");
MethodInfo containsMethod = dictionaryType.GetMethod("Contains") ?? dictionaryType.GetMethod("ContainsKey");
ObjectGenerator objectGenerator = new ObjectGenerator();
for (int i = 0; i < size; i++)
{
object newKey = objectGenerator.GenerateObject(typeK, createdObjectReferences);
if (newKey == null)
{
// Cannot generate a valid key
return null;
}
bool containsKey = (bool)containsMethod.Invoke(result, new object[] { newKey });
if (!containsKey)
{
object newValue = objectGenerator.GenerateObject(typeV, createdObjectReferences);
addMethod.Invoke(result, new object[] { newKey, newValue });
}
}
return result;
}
private static object GenerateEnum(Type enumType)
{
Array possibleValues = Enum.GetValues(enumType);
if (possibleValues.Length > 0)
{
return possibleValues.GetValue(0);
}
return null;
}
private static object GenerateQueryable(Type queryableType, int size, Dictionary<Type, object> createdObjectReferences)
{
bool isGeneric = queryableType.IsGenericType;
object list;
if (isGeneric)
{
Type listType = typeof(List<>).MakeGenericType(queryableType.GetGenericArguments());
list = GenerateCollection(listType, size, createdObjectReferences);
}
else
{
list = GenerateArray(typeof(object[]), size, createdObjectReferences);
}
if (list == null)
{
return null;
}
if (isGeneric)
{
Type argumentType = typeof(IEnumerable<>).MakeGenericType(queryableType.GetGenericArguments());
MethodInfo asQueryableMethod = typeof(Queryable).GetMethod("AsQueryable", new[] { argumentType });
return asQueryableMethod.Invoke(null, new[] { list });
}
return Queryable.AsQueryable((IEnumerable)list);
}
private static object GenerateCollection(Type collectionType, int size, Dictionary<Type, object> createdObjectReferences)
{
Type type = collectionType.IsGenericType ?
collectionType.GetGenericArguments()[0] :
typeof(object);
object result = Activator.CreateInstance(collectionType);
MethodInfo addMethod = collectionType.GetMethod("Add");
bool areAllElementsNull = true;
ObjectGenerator objectGenerator = new ObjectGenerator();
for (int i = 0; i < size; i++)
{
object element = objectGenerator.GenerateObject(type, createdObjectReferences);
addMethod.Invoke(result, new object[] { element });
areAllElementsNull &= element == null;
}
if (areAllElementsNull)
{
return null;
}
return result;
}
private static object GenerateNullable(Type nullableType, Dictionary<Type, object> createdObjectReferences)
{
Type type = nullableType.GetGenericArguments()[0];
ObjectGenerator objectGenerator = new ObjectGenerator();
return objectGenerator.GenerateObject(type, createdObjectReferences);
}
private static object GenerateComplexObject(Type type, Dictionary<Type, object> createdObjectReferences)
{
object result = null;
if (createdObjectReferences.TryGetValue(type, out result))
{
// The object has been created already, just return it. This will handle the circular reference case.
return result;
}
if (type.IsValueType)
{
result = Activator.CreateInstance(type);
}
else
{
ConstructorInfo defaultCtor = type.GetConstructor(Type.EmptyTypes);
if (defaultCtor == null)
{
// Cannot instantiate the type because it doesn't have a default constructor
return null;
}
result = defaultCtor.Invoke(new object[0]);
}
createdObjectReferences.Add(type, result);
SetPublicProperties(type, result, createdObjectReferences);
SetPublicFields(type, result, createdObjectReferences);
return result;
}
private static void SetPublicProperties(Type type, object obj, Dictionary<Type, object> createdObjectReferences)
{
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
ObjectGenerator objectGenerator = new ObjectGenerator();
foreach (PropertyInfo property in properties)
{
if (property.CanWrite)
{
object propertyValue = objectGenerator.GenerateObject(property.PropertyType, createdObjectReferences);
property.SetValue(obj, propertyValue, null);
}
}
}
private static void SetPublicFields(Type type, object obj, Dictionary<Type, object> createdObjectReferences)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
ObjectGenerator objectGenerator = new ObjectGenerator();
foreach (FieldInfo field in fields)
{
object fieldValue = objectGenerator.GenerateObject(field.FieldType, createdObjectReferences);
field.SetValue(obj, fieldValue);
}
}
private class SimpleTypeObjectGenerator
{
private long _index = 0;
private static readonly Dictionary<Type, Func<long, object>> DefaultGenerators = InitializeGenerators();
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These are simple type factories and cannot be split up.")]
private static Dictionary<Type, Func<long, object>> InitializeGenerators()
{
return new Dictionary<Type, Func<long, object>>
{
{ typeof(Boolean), index => true },
{ typeof(Byte), index => (Byte)64 },
{ typeof(Char), index => (Char)65 },
{ typeof(DateTime), index => DateTime.Now },
{ typeof(DateTimeOffset), index => new DateTimeOffset(DateTime.Now) },
{ typeof(DBNull), index => DBNull.Value },
{ typeof(Decimal), index => (Decimal)index },
{ typeof(Double), index => (Double)(index + 0.1) },
{ typeof(Guid), index => Guid.NewGuid() },
{ typeof(Int16), index => (Int16)(index % Int16.MaxValue) },
{ typeof(Int32), index => (Int32)(index % Int32.MaxValue) },
{ typeof(Int64), index => (Int64)index },
{ typeof(Object), index => new object() },
{ typeof(SByte), index => (SByte)64 },
{ typeof(Single), index => (Single)(index + 0.1) },
{
typeof(String), index =>
{
return String.Format(CultureInfo.CurrentCulture, "sample string {0}", index);
}
},
{
typeof(TimeSpan), index =>
{
return TimeSpan.FromTicks(1234567);
}
},
{ typeof(UInt16), index => (UInt16)(index % UInt16.MaxValue) },
{ typeof(UInt32), index => (UInt32)(index % UInt32.MaxValue) },
{ typeof(UInt64), index => (UInt64)index },
{
typeof(Uri), index =>
{
return new Uri(String.Format(CultureInfo.CurrentCulture, "http://webapihelppage{0}.com", index));
}
},
};
}
public static bool CanGenerateObject(Type type)
{
return DefaultGenerators.ContainsKey(type);
}
public object GenerateObject(Type type)
{
return DefaultGenerators[type](++_index);
}
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// Indicates whether the sample is used for request or response
/// </summary>
public enum SampleDirection
{
Request = 0,
Response
}
}

Просмотреть файл

@ -0,0 +1,37 @@
using System;
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// This represents a preformatted text sample on the help page. There's a display template named TextSample associated with this class.
/// </summary>
public class TextSample
{
public TextSample(string text)
{
if (text == null)
{
throw new ArgumentNullException("text");
}
Text = text;
}
public string Text { get; private set; }
public override bool Equals(object obj)
{
TextSample other = obj as TextSample;
return other != null && Text == other.Text;
}
public override int GetHashCode()
{
return Text.GetHashCode();
}
public override string ToString()
{
return Text;
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
@using System.Web.Http
@using InsuranceAPI.Areas.HelpPage.Models
@model HelpPageApiModel
@{
var description = Model.ApiDescription;
ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath;
}
<link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
<div id="body" class="help-page">
<section class="featured">
<div class="content-wrapper">
<p>
@Html.ActionLink("Help Page Home", "Index")
</p>
</div>
</section>
<section class="content-wrapper main-content clear-fix">
@Html.DisplayForModel()
</section>
</div>

Просмотреть файл

@ -0,0 +1,41 @@
@using System.Web.Http
@using System.Web.Http.Controllers
@using System.Web.Http.Description
@using InsuranceAPI.Areas.HelpPage
@using InsuranceAPI.Areas.HelpPage.Models
@model IGrouping<HttpControllerDescriptor, ApiDescription>
@{
var controllerDocumentation = ViewBag.DocumentationProvider != null ?
ViewBag.DocumentationProvider.GetDocumentation(Model.Key) :
null;
}
<h2 id="@Model.Key.ControllerName">@Model.Key.ControllerName</h2>
@if (!String.IsNullOrEmpty(controllerDocumentation))
{
<p>@controllerDocumentation</p>
}
<table class="help-page-table">
<thead>
<tr><th>API</th><th>Description</th></tr>
</thead>
<tbody>
@foreach (var api in Model)
{
<tr>
<td class="api-name"><a href="@Url.Action("Api", "Help", new { apiId = api.GetFriendlyId() })">@api.HttpMethod.Method @api.RelativePath</a></td>
<td class="api-documentation">
@if (api.Documentation != null)
{
<p>@api.Documentation</p>
}
else
{
<p>No documentation available.</p>
}
</td>
</tr>
}
</tbody>
</table>

Просмотреть файл

@ -0,0 +1,6 @@
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model CollectionModelDescription
@if (Model.ElementDescription is ComplexTypeModelDescription)
{
@Html.DisplayFor(m => m.ElementDescription)
}

Просмотреть файл

@ -0,0 +1,3 @@
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model ComplexTypeModelDescription
@Html.DisplayFor(m => m.Properties, "Parameters")

Просмотреть файл

@ -0,0 +1,4 @@
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model DictionaryModelDescription
Dictionary of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key]
and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value]

Просмотреть файл

@ -0,0 +1,24 @@
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model EnumTypeModelDescription
<p>Possible enumeration values:</p>
<table class="help-page-table">
<thead>
<tr><th>Name</th><th>Value</th><th>Description</th></tr>
</thead>
<tbody>
@foreach (EnumValueDescription value in Model.Values)
{
<tr>
<td class="enum-name"><b>@value.Name</b></td>
<td class="enum-value">
<p>@value.Value</p>
</td>
<td class="enum-description">
<p>@value.Documentation</p>
</td>
</tr>
}
</tbody>
</table>

Просмотреть файл

@ -0,0 +1,67 @@
@using System.Web.Http
@using System.Web.Http.Description
@using InsuranceAPI.Areas.HelpPage.Models
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model HelpPageApiModel
@{
ApiDescription description = Model.ApiDescription;
}
<h1>@description.HttpMethod.Method @description.RelativePath</h1>
<div>
<p>@description.Documentation</p>
<h2>Request Information</h2>
<h3>URI Parameters</h3>
@Html.DisplayFor(m => m.UriParameters, "Parameters")
<h3>Body Parameters</h3>
<p>@Model.RequestDocumentation</p>
@if (Model.RequestModelDescription != null)
{
@Html.DisplayFor(m => m.RequestModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.RequestModelDescription })
if (Model.RequestBodyParameters != null)
{
@Html.DisplayFor(m => m.RequestBodyParameters, "Parameters")
}
}
else
{
<p>None.</p>
}
@if (Model.SampleRequests.Count > 0)
{
<h3>Request Formats</h3>
@Html.DisplayFor(m => m.SampleRequests, "Samples")
}
<h2>Response Information</h2>
<h3>Resource Description</h3>
<p>@description.ResponseDescription.Documentation</p>
@if (Model.ResourceDescription != null)
{
@Html.DisplayFor(m => m.ResourceDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ResourceDescription })
if (Model.ResourceProperties != null)
{
@Html.DisplayFor(m => m.ResourceProperties, "Parameters")
}
}
else
{
<p>None.</p>
}
@if (Model.SampleResponses.Count > 0)
{
<h3>Response Formats</h3>
@Html.DisplayFor(m => m.SampleResponses, "Samples")
}
</div>

Просмотреть файл

@ -0,0 +1,4 @@
@using InsuranceAPI.Areas.HelpPage
@model ImageSample
<img src="@Model.Src" />

Просмотреть файл

@ -0,0 +1,13 @@
@using InsuranceAPI.Areas.HelpPage
@model InvalidSample
@if (HttpContext.Current.IsDebuggingEnabled)
{
<div class="warning-message-container">
<p>@Model.ErrorMessage</p>
</div>
}
else
{
<p>Sample not available.</p>
}

Просмотреть файл

@ -0,0 +1,4 @@
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model KeyValuePairModelDescription
Pair of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key]
and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value]

Просмотреть файл

@ -0,0 +1,26 @@
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model Type
@{
ModelDescription modelDescription = ViewBag.modelDescription;
if (modelDescription is ComplexTypeModelDescription || modelDescription is EnumTypeModelDescription)
{
if (Model == typeof(Object))
{
@:Object
}
else
{
@Html.ActionLink(modelDescription.Name, "ResourceModel", "Help", new { modelName = modelDescription.Name }, null)
}
}
else if (modelDescription is CollectionModelDescription)
{
var collectionDescription = modelDescription as CollectionModelDescription;
var elementDescription = collectionDescription.ElementDescription;
@:Collection of @Html.DisplayFor(m => elementDescription.ModelType, "ModelDescriptionLink", new { modelDescription = elementDescription })
}
else
{
@Html.DisplayFor(m => modelDescription)
}
}

Просмотреть файл

@ -0,0 +1,48 @@
@using System.Collections.Generic
@using System.Collections.ObjectModel
@using System.Web.Http.Description
@using System.Threading
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model IList<ParameterDescription>
@if (Model.Count > 0)
{
<table class="help-page-table">
<thead>
<tr><th>Name</th><th>Description</th><th>Type</th><th>Additional information</th></tr>
</thead>
<tbody>
@foreach (ParameterDescription parameter in Model)
{
ModelDescription modelDescription = parameter.TypeDescription;
<tr>
<td class="parameter-name">@parameter.Name</td>
<td class="parameter-documentation">
<p>@parameter.Documentation</p>
</td>
<td class="parameter-type">
@Html.DisplayFor(m => modelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = modelDescription })
</td>
<td class="parameter-annotations">
@if (parameter.Annotations.Count > 0)
{
foreach (var annotation in parameter.Annotations)
{
<p>@annotation.Documentation</p>
}
}
else
{
<p>None.</p>
}
</td>
</tr>
}
</tbody>
</table>
}
else
{
<p>None.</p>
}

Просмотреть файл

@ -0,0 +1,30 @@
@using System.Net.Http.Headers
@model Dictionary<MediaTypeHeaderValue, object>
@{
// Group the samples into a single tab if they are the same.
Dictionary<string, object> samples = Model.GroupBy(pair => pair.Value).ToDictionary(
pair => String.Join(", ", pair.Select(m => m.Key.ToString()).ToArray()),
pair => pair.Key);
var mediaTypes = samples.Keys;
}
<div>
@foreach (var mediaType in mediaTypes)
{
<h4 class="sample-header">@mediaType</h4>
<div class="sample-content">
<span><b>Sample:</b></span>
@{
var sample = samples[mediaType];
if (sample == null)
{
<p>Sample not available.</p>
}
else
{
@Html.DisplayFor(s => sample);
}
}
</div>
}
</div>

Просмотреть файл

@ -0,0 +1,3 @@
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model SimpleTypeModelDescription
@Model.Documentation

Просмотреть файл

@ -0,0 +1,6 @@
@using InsuranceAPI.Areas.HelpPage
@model TextSample
<pre class="wrapped">
@Model.Text
</pre>

Просмотреть файл

@ -0,0 +1,38 @@
@using System.Web.Http
@using System.Web.Http.Controllers
@using System.Web.Http.Description
@using System.Collections.ObjectModel
@using InsuranceAPI.Areas.HelpPage.Models
@model Collection<ApiDescription>
@{
ViewBag.Title = "ASP.NET Web API Help Page";
// Group APIs by controller
ILookup<HttpControllerDescriptor, ApiDescription> apiGroups = Model.ToLookup(api => api.ActionDescriptor.ControllerDescriptor);
}
<link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
<header class="help-page">
<div class="content-wrapper">
<div class="float-left">
<h1>@ViewBag.Title</h1>
</div>
</div>
</header>
<div id="body" class="help-page">
<section class="featured">
<div class="content-wrapper">
<h2>Introduction</h2>
<p>
Provide a general description of your APIs here.
</p>
</div>
</section>
<section class="content-wrapper main-content clear-fix">
@foreach (var group in apiGroups)
{
@Html.DisplayFor(m => group, "ApiGroup")
}
</section>
</div>

Просмотреть файл

@ -0,0 +1,19 @@
@using System.Web.Http
@using InsuranceAPI.Areas.HelpPage.ModelDescriptions
@model ModelDescription
<link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
<div id="body" class="help-page">
<section class="featured">
<div class="content-wrapper">
<p>
@Html.ActionLink("Help Page Home", "Index")
</p>
</div>
</section>
<h1>@Model.Name</h1>
<p>@Model.Documentation</p>
<section class="content-wrapper main-content clear-fix">
@Html.DisplayFor(m => Model)
</section>
</div>

Просмотреть файл

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@RenderSection("scripts", required: false)
</head>
<body>
@RenderBody()
</body>
</html>

Просмотреть файл

@ -0,0 +1,41 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</assemblies>
</compilation>
</system.web>
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>

Просмотреть файл

@ -0,0 +1,4 @@
@{
// Change the Layout path below to blend the look and feel of the help page with your existing web pages.
Layout = "~/Areas/HelpPage/Views/Shared/_Layout.cshtml";
}

Просмотреть файл

@ -0,0 +1,161 @@
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using System.Xml.XPath;
using InsuranceAPI.Areas.HelpPage.ModelDescriptions;
namespace InsuranceAPI.Areas.HelpPage
{
/// <summary>
/// A custom <see cref="IDocumentationProvider"/> that reads the API documentation from an XML documentation file.
/// </summary>
public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
private XPathNavigator _documentNavigator;
private const string TypeExpression = "/doc/members/member[@name='T:{0}']";
private const string MethodExpression = "/doc/members/member[@name='M:{0}']";
private const string PropertyExpression = "/doc/members/member[@name='P:{0}']";
private const string FieldExpression = "/doc/members/member[@name='F:{0}']";
private const string ParameterExpression = "param[@name='{0}']";
/// <summary>
/// Initializes a new instance of the <see cref="XmlDocumentationProvider"/> class.
/// </summary>
/// <param name="documentPath">The physical path to XML document.</param>
public XmlDocumentationProvider(string documentPath)
{
if (documentPath == null)
{
throw new ArgumentNullException("documentPath");
}
XPathDocument xpath = new XPathDocument(documentPath);
_documentNavigator = xpath.CreateNavigator();
}
public string GetDocumentation(HttpControllerDescriptor controllerDescriptor)
{
XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType);
return GetTagValue(typeNode, "summary");
}
public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "summary");
}
public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
if (reflectedParameterDescriptor != null)
{
XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);
if (methodNode != null)
{
string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName));
if (parameterNode != null)
{
return parameterNode.Value.Trim();
}
}
}
return null;
}
public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "returns");
}
public string GetDocumentation(MemberInfo member)
{
string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name);
string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression;
string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName);
XPathNavigator propertyNode = _documentNavigator.SelectSingleNode(selectExpression);
return GetTagValue(propertyNode, "summary");
}
public string GetDocumentation(Type type)
{
XPathNavigator typeNode = GetTypeNode(type);
return GetTagValue(typeNode, "summary");
}
private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor)
{
ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
if (reflectedActionDescriptor != null)
{
string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
return _documentNavigator.SelectSingleNode(selectExpression);
}
return null;
}
private static string GetMemberName(MethodInfo method)
{
string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name);
ParameterInfo[] parameters = method.GetParameters();
if (parameters.Length != 0)
{
string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray();
name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames));
}
return name;
}
private static string GetTagValue(XPathNavigator parentNode, string tagName)
{
if (parentNode != null)
{
XPathNavigator node = parentNode.SelectSingleNode(tagName);
if (node != null)
{
return node.Value.Trim();
}
}
return null;
}
private XPathNavigator GetTypeNode(Type type)
{
string controllerTypeName = GetTypeName(type);
string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName);
return _documentNavigator.SelectSingleNode(selectExpression);
}
private static string GetTypeName(Type type)
{
string name = type.FullName;
if (type.IsGenericType)
{
// Format the generic type name to something like: Generic{System.Int32,System.String}
Type genericType = type.GetGenericTypeDefinition();
Type[] genericArguments = type.GetGenericArguments();
string genericTypeName = genericType.FullName;
// Trim the generic parameter counts from the name
genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));
string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();
name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames));
}
if (type.IsNested)
{
// Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax.
name = name.Replace("+", ".");
}
return name;
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InsuranceAPI
{
using System;
using System.Collections.Generic;
public partial class Claim
{
public System.Guid ClaimId { get; set; }
public Nullable<System.Guid> AccidentId { get; set; }
public string Status { get; set; }
public Nullable<System.DateTime> ModifyDate { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,17 @@
body {
padding-top: 50px;
padding-bottom: 20px;
}
/* Set padding to keep content from hitting the edges */
.body-content {
padding-left: 15px;
padding-right: 15px;
}
/* Set width on the form input elements since they're 100% wide by default */
input,
select,
textarea {
max-width: 280px;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,331 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace InsuranceAPI.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace InsuranceAPI.Controllers
{
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
}

Просмотреть файл

@ -0,0 +1 @@
<%@ Application Codebehind="Global.asax.cs" Inherits="InsuranceAPI.WebApiApplication" Language="C#" %>

Просмотреть файл

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
//add these using statements
using Microsoft.Azure.KeyVault;
using System.Web.Configuration;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider;
using System.Data.SqlClient;
namespace InsuranceAPI
{
public class WebApiApplication : System.Web.HttpApplication
{
private static ClientCredential _clientCredential;
async protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
string clientId = WebConfigurationManager.AppSettings["ClientId"];
string clientSecret = WebConfigurationManager.AppSettings["ClientSecret"];
_clientCredential = new ClientCredential(clientId, clientSecret);
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(Util.GetToken);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(Util.GetToken));
var sec = await kv.GetSecretAsync(WebConfigurationManager.AppSettings["SecretUri"]);
Util.EncryptSecret = sec.Value;
}
}
}

Просмотреть файл

@ -0,0 +1,465 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\EntityFramework.6.4.0\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.props')" />
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props')" />
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.5\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.5\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="..\packages\Microsoft.Net.Compilers.2.1.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.1.0\build\Microsoft.Net.Compilers.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EB449E3C-3C97-468F-B78C-AF1204CA11D5}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>InsuranceAPI</RootNamespace>
<AssemblyName>InsuranceAPI</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TypeScriptToolsVersion>3.1</TypeScriptToolsVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Antlr3.Runtime, Version=3.5.0.2, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
<HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.Agent.Intercept, Version=2.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ApplicationInsights.Agent.Intercept.2.4.0\lib\net45\Microsoft.AI.Agent.Intercept.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.DependencyCollector, Version=2.9.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.9.1\lib\net45\Microsoft.AI.DependencyCollector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.PerfCounterCollector, Version=2.9.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.9.1\lib\net45\Microsoft.AI.PerfCounterCollector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.ServerTelemetryChannel, Version=2.9.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.9.1\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.Web, Version=2.9.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ApplicationInsights.Web.2.9.1\lib\net45\Microsoft.AI.Web.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.WindowsServer, Version=2.9.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ApplicationInsights.WindowsServer.2.9.1\lib\net45\Microsoft.AI.WindowsServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ApplicationInsights, Version=2.9.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.ApplicationInsights.2.9.1\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.TelemetryCorrelation, Version=1.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.TelemetryCorrelation.1.0.5\lib\net45\Microsoft.AspNet.TelemetryCorrelation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.KeyVault, Version=3.0.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Azure.KeyVault.3.0.4\lib\net461\Microsoft.Azure.KeyVault.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.KeyVault.WebKey, Version=3.0.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Azure.KeyVault.WebKey.3.0.4\lib\net461\Microsoft.Azure.KeyVault.WebKey.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.16.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.16.204221202\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms, Version=2.16.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.16.204221202\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Rest.ClientRuntime.2.3.20\lib\net461\Microsoft.Rest.ClientRuntime.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime.Azure, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.19\lib\net461\Microsoft.Rest.ClientRuntime.Azure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider, Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider.2.2.0\lib\net46\Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.3.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.5.1\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.Management" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Security" />
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.7\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Routing" />
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest">
</Reference>
<Reference Include="System.Web.Optimization">
<HintPath>..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="WebGrease, Version=1.6.5135.21930, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\WebGrease.1.6.0\lib\WebGrease.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Accident.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="Agent.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="App_Start\BundleConfig.cs" />
<Compile Include="App_Start\FilterConfig.cs" />
<Compile Include="App_Start\RouteConfig.cs" />
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="Areas\HelpPage\ApiDescriptionExtensions.cs" />
<Compile Include="Areas\HelpPage\App_Start\HelpPageConfig.cs" />
<Compile Include="Areas\HelpPage\Controllers\HelpController.cs" />
<Compile Include="Areas\HelpPage\HelpPageAreaRegistration.cs" />
<Compile Include="Areas\HelpPage\HelpPageConfigurationExtensions.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\CollectionModelDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\ComplexTypeModelDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\DictionaryModelDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\EnumTypeModelDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\EnumValueDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\IModelDocumentationProvider.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\KeyValuePairModelDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelDescriptionGenerator.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelNameAttribute.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\ModelNameHelper.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\ParameterAnnotation.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\ParameterDescription.cs" />
<Compile Include="Areas\HelpPage\ModelDescriptions\SimpleTypeModelDescription.cs" />
<Compile Include="Areas\HelpPage\Models\HelpPageApiModel.cs" />
<Compile Include="Areas\HelpPage\SampleGeneration\HelpPageSampleGenerator.cs" />
<Compile Include="Areas\HelpPage\SampleGeneration\HelpPageSampleKey.cs" />
<Compile Include="Areas\HelpPage\SampleGeneration\ImageSample.cs" />
<Compile Include="Areas\HelpPage\SampleGeneration\InvalidSample.cs" />
<Compile Include="Areas\HelpPage\SampleGeneration\ObjectGenerator.cs" />
<Compile Include="Areas\HelpPage\SampleGeneration\SampleDirection.cs" />
<Compile Include="Areas\HelpPage\SampleGeneration\TextSample.cs" />
<Compile Include="Areas\HelpPage\XmlDocumentationProvider.cs" />
<Compile Include="Claim.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="InsuranceEntities.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Controllers\ValuesController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
<Compile Include="Model1.Context.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Model1.Context.tt</DependentUpon>
</Compile>
<Compile Include="Model1.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="Model1.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Model1.edmx</DependentUpon>
</Compile>
<Compile Include="Order.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="Participant.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="Policy.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="User.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="UsersController.cs" />
<Compile Include="UserVehicle.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="Util.cs" />
<Compile Include="vAgentUser.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="vAgentUsersController.cs" />
<Compile Include="Vehicle.cs">
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="Areas\HelpPage\HelpPage.css" />
<Content Include="Content\bootstrap-grid.css" />
<Content Include="Content\bootstrap-grid.min.css" />
<Content Include="Content\bootstrap-reboot.css" />
<Content Include="Content\bootstrap-reboot.min.css" />
<Content Include="Content\bootstrap.css" />
<Content Include="Content\bootstrap.min.css" />
<Content Include="favicon.ico" />
<Content Include="Global.asax" />
<Content Include="Model1.Context.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Model1.Context.cs</LastGenOutput>
<DependentUpon>Model1.edmx</DependentUpon>
</Content>
<Content Include="Model1.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<DependentUpon>Model1.edmx</DependentUpon>
<LastGenOutput>Model1.cs</LastGenOutput>
</Content>
<Content Include="ApplicationInsights.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<EntityDeploy Include="Model1.edmx">
<Generator>EntityModelCodeGenerator</Generator>
<LastGenOutput>Model1.Designer.cs</LastGenOutput>
</EntityDeploy>
<Content Include="Model1.edmx.diagram">
<DependentUpon>Model1.edmx</DependentUpon>
</Content>
<Content Include="Scripts\bootstrap.bundle.js" />
<Content Include="Scripts\bootstrap.bundle.min.js" />
<Content Include="Scripts\bootstrap.js" />
<Content Include="Scripts\bootstrap.min.js" />
<Content Include="Scripts\bootstrap.min.js.map" />
<Content Include="Scripts\bootstrap.js.map" />
<Content Include="Scripts\bootstrap.bundle.min.js.map" />
<Content Include="Scripts\bootstrap.bundle.js.map" />
<Content Include="Content\bootstrap.min.css.map" />
<Content Include="Content\bootstrap.css.map" />
<Content Include="Content\bootstrap-reboot.min.css.map" />
<Content Include="Content\bootstrap-reboot.css.map" />
<Content Include="Content\bootstrap-grid.min.css.map" />
<Content Include="Content\bootstrap-grid.css.map" />
<Content Include="Scripts\esm\popper-utils.js" />
<Content Include="Scripts\esm\popper-utils.min.js" />
<Content Include="Scripts\esm\popper.js" />
<Content Include="Scripts\esm\popper.min.js" />
<Content Include="Scripts\esm\popper.min.js.map" />
<Content Include="Scripts\esm\popper.js.map" />
<Content Include="Scripts\esm\popper-utils.min.js.map" />
<Content Include="Scripts\esm\popper-utils.js.map" />
<Content Include="Areas\HelpPage\Views\_ViewStart.cshtml" />
<Content Include="Areas\HelpPage\Views\Web.config" />
<Content Include="Areas\HelpPage\Views\Shared\_Layout.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\ResourceModel.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\Index.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\TextSample.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\SimpleTypeModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\Samples.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\Parameters.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ModelDescriptionLink.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\KeyValuePairModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\InvalidSample.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ImageSample.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\HelpPageApiModel.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\EnumTypeModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\DictionaryModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ComplexTypeModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\CollectionModelDescription.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ApiGroup.cshtml" />
<Content Include="Areas\HelpPage\Views\Help\Api.cshtml" />
<None Include="Scripts\jquery-3.3.1.intellisense.js" />
<Content Include="Scripts\jquery-3.3.1.js" />
<Content Include="Scripts\jquery-3.3.1.min.js" />
<Content Include="Scripts\jquery-3.3.1.slim.js" />
<Content Include="Scripts\jquery-3.3.1.slim.min.js" />
<Content Include="Scripts\modernizr-2.8.3.js" />
<Content Include="Scripts\popper-utils.js" />
<Content Include="Scripts\popper-utils.min.js" />
<Content Include="Scripts\popper.js" />
<Content Include="Scripts\popper.min.js" />
<Content Include="Scripts\respond.js" />
<Content Include="Scripts\respond.matchmedia.addListener.js" />
<Content Include="Scripts\respond.matchmedia.addListener.min.js" />
<Content Include="Scripts\respond.min.js" />
<Content Include="Scripts\umd\popper-utils.js" />
<Content Include="Scripts\umd\popper-utils.min.js" />
<Content Include="Scripts\umd\popper.js" />
<Content Include="Scripts\umd\popper.min.js" />
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</Content>
<Content Include="Content\Site.css" />
<Content Include="Views\Web.config" />
<Content Include="Views\_ViewStart.cshtml" />
<Content Include="Views\Home\Index.cshtml" />
<Content Include="Views\Shared\Error.cshtml" />
<Content Include="Views\Shared\_Layout.cshtml" />
<Content Include="Scripts\umd\popper.min.js.map" />
<Content Include="Scripts\umd\popper.js.map" />
<Content Include="Scripts\umd\popper-utils.min.js.map" />
<Content Include="Scripts\umd\popper-utils.js.map" />
<Content Include="Scripts\README.md" />
<Content Include="Scripts\popper.min.js.map" />
<Content Include="Scripts\popper.js.map" />
<Content Include="Scripts\popper-utils.min.js.map" />
<Content Include="Scripts\popper-utils.js.map" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
<Folder Include="Models\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<Content Include="Scripts\jquery-3.3.1.slim.min.map" />
<Content Include="Scripts\jquery-3.3.1.min.map" />
</ItemGroup>
<ItemGroup>
<Service Include="{4A0DDDB5-7A95-4FBF-97CC-616D07737A77}" />
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<ItemGroup>
<TypeScriptCompile Include="Scripts\index.d.ts" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets')" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>24448</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:24448/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
<Error Condition="!Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.0\build\EntityFramework.props'))" />
<Error Condition="!Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.0\build\EntityFramework.targets'))" />
</Target>
<Import Project="..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.9.1\build\Microsoft.ApplicationInsights.DependencyCollector.targets" Condition="Exists('..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.9.1\build\Microsoft.ApplicationInsights.DependencyCollector.targets')" />
<Import Project="..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.9.1\build\Microsoft.ApplicationInsights.PerfCounterCollector.targets" Condition="Exists('..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.9.1\build\Microsoft.ApplicationInsights.PerfCounterCollector.targets')" />
<Import Project="..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.9.1\build\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.targets" Condition="Exists('..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.9.1\build\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.targets')" />
<Import Project="..\packages\Microsoft.ApplicationInsights.WindowsServer.2.9.1\build\Microsoft.ApplicationInsights.WindowsServer.targets" Condition="Exists('..\packages\Microsoft.ApplicationInsights.WindowsServer.2.9.1\build\Microsoft.ApplicationInsights.WindowsServer.targets')" />
<Import Project="..\packages\Microsoft.ApplicationInsights.Web.2.9.1\build\Microsoft.ApplicationInsights.Web.targets" Condition="Exists('..\packages\Microsoft.ApplicationInsights.Web.2.9.1\build\Microsoft.ApplicationInsights.Web.targets')" />
<Import Project="..\packages\EntityFramework.6.4.0\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target> -->
</Project>

Просмотреть файл

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace InsuranceAPI
{
public partial class InsuranceEntities
{
public InsuranceEntities(string connectionString) : base(connectionString)
{
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InsuranceAPI
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class InsuranceEntities : DbContext
{
public InsuranceEntities()
: base("name=InsuranceEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
public virtual DbSet<Claim> Claims { get; set; }
public virtual DbSet<Order> Orders { get; set; }
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<UserVehicle> UserVehicles { get; set; }
public virtual DbSet<Vehicle> Vehicles { get; set; }
public virtual DbSet<Accident> Accidents { get; set; }
public virtual DbSet<Agent> Agents { get; set; }
public virtual DbSet<Participant> Participants { get; set; }
public virtual DbSet<Policy> Policies { get; set; }
public virtual DbSet<vAgentUser> vAgentUsers { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,636 @@
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
output extension=".cs"#><#
const string inputFile = @"Model1.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
var itemCollection = loader.CreateEdmItemCollection(inputFile);
var modelNamespace = loader.GetModelNamespace(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
if (container == null)
{
return string.Empty;
}
#>
//------------------------------------------------------------------------------
// <auto-generated>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
//
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
// </auto-generated>
//------------------------------------------------------------------------------
<#
var codeNamespace = code.VsNamespaceSuggestion();
if (!String.IsNullOrEmpty(codeNamespace))
{
#>
namespace <#=code.EscapeNamespace(codeNamespace)#>
{
<#
PushIndent(" ");
}
#>
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
<#
if (container.FunctionImports.Any())
{
#>
using System.Data.Entity.Core.Objects;
using System.Linq;
<#
}
#>
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoadingEnabled = false;
<#
}
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
// Note: the DbSet members are defined below such that the getter and
// setter always have the same accessibility as the DbSet definition
if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
{
#>
<#=codeStringGenerator.DbSetInitializer(entitySet)#>
<#
}
}
#>
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
<#
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
#>
<#=codeStringGenerator.DbSet(entitySet)#>
<#
}
foreach (var edmFunction in container.FunctionImports)
{
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
}
#>
}
<#
if (!String.IsNullOrEmpty(codeNamespace))
{
PopIndent();
#>
}
<#
}
#>
<#+
private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
if (typeMapper.IsComposable(edmFunction))
{
#>
[DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
<#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
{
<#+
codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
#>
<#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
}
<#+
}
else
{
#>
<#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
{
<#+
codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
#>
<#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
}
<#+
if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
{
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
}
}
}
public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
{
#>
var <#=name#> = <#=isNotNull#> ?
<#=notNullInit#> :
<#=nullInit#>;
<#+
}
public const string TemplateId = "CSharp_DbContext_Context_EF6";
public class CodeStringGenerator
{
private readonly CodeGenerationTools _code;
private readonly TypeMapper _typeMapper;
private readonly MetadataTools _ef;
public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(typeMapper, "typeMapper");
ArgumentNotNull(ef, "ef");
_code = code;
_typeMapper = typeMapper;
_ef = ef;
}
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
public string AccessibilityAndVirtual(string accessibility)
{
return accessibility + (accessibility != "private" ? " virtual" : "");
}
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
public string EnumOpening(SimpleType enumType)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} enum {1} : {2}",
Accessibility.ForType(enumType),
_code.Escape(enumType),
_code.Escape(_typeMapper.UnderlyingClrType(enumType)));
}
public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
{
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
{
var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
}
}
public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"{0} IQueryable<{1}> {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
_code.Escape(edmFunction),
string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
}
public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
edmFunction.NamespaceName,
edmFunction.Name,
string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
_code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
}
public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
if (includeMergeOption)
{
paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
}
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
_code.Escape(edmFunction),
paramList);
}
public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
if (includeMergeOption)
{
callParams = ", mergeOption" + callParams;
}
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
edmFunction.Name,
callParams);
}
public string DbSet(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} virtual DbSet<{1}> {2} {{ get; set; }}",
Accessibility.ForReadOnlyProperty(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType),
_code.Escape(entitySet));
}
public string DbSetInitializer(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} = Set<{1}>();",
_code.Escape(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType));
}
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"{2}",
inHeader ? Environment.NewLine : "",
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
}
public class TypeMapper
{
private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
private readonly System.Collections.IList _errors;
private readonly CodeGenerationTools _code;
private readonly MetadataTools _ef;
public static string FixNamespaces(string typeName)
{
return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
}
public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(ef, "ef");
ArgumentNotNull(errors, "errors");
_code = code;
_ef = ef;
_errors = errors;
}
public string GetTypeName(TypeUsage typeUsage)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
}
public string GetTypeName(EdmType edmType)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: null);
}
public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
}
public string GetTypeName(EdmType edmType, string modelNamespace)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
}
public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
{
if (edmType == null)
{
return null;
}
var collectionType = edmType as CollectionType;
if (collectionType != null)
{
return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
}
var typeName = _code.Escape(edmType.MetadataProperties
.Where(p => p.Name == ExternalTypeNameAttributeName)
.Select(p => (string)p.Value)
.FirstOrDefault())
?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
_code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
_code.Escape(edmType));
if (edmType is StructuralType)
{
return typeName;
}
if (edmType is SimpleType)
{
var clrType = UnderlyingClrType(edmType);
if (!IsEnumType(edmType))
{
typeName = _code.Escape(clrType);
}
typeName = FixNamespaces(typeName);
return clrType.IsValueType && isNullable == true ?
String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
typeName;
}
throw new ArgumentException("edmType");
}
public Type UnderlyingClrType(EdmType edmType)
{
ArgumentNotNull(edmType, "edmType");
var primitiveType = edmType as PrimitiveType;
if (primitiveType != null)
{
return primitiveType.ClrEquivalentType;
}
if (IsEnumType(edmType))
{
return GetEnumUnderlyingType(edmType).ClrEquivalentType;
}
return typeof(object);
}
public object GetEnumMemberValue(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var valueProperty = enumMember.GetType().GetProperty("Value");
return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
}
public string GetEnumMemberName(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var nameProperty = enumMember.GetType().GetProperty("Name");
return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
}
public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var membersProperty = enumType.GetType().GetProperty("Members");
return membersProperty != null
? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
: Enumerable.Empty<MetadataItem>();
}
public bool EnumIsFlags(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
}
public bool IsEnumType(GlobalItem edmType)
{
ArgumentNotNull(edmType, "edmType");
return edmType.GetType().Name == "EnumType";
}
public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
}
public string CreateLiteral(object value)
{
if (value == null || value.GetType() != typeof(TimeSpan))
{
return _code.CreateLiteral(value);
}
return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
}
public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
{
ArgumentNotNull(types, "types");
ArgumentNotNull(sourceFile, "sourceFile");
var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
if (types.Any(item => !hash.Add(item)))
{
_errors.Add(
new CompilerError(sourceFile, -1, -1, "6023",
String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
return false;
}
return true;
}
public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
{
return GetItemsToGenerate<SimpleType>(itemCollection)
.Where(e => IsEnumType(e));
}
public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
{
return itemCollection
.OfType<T>()
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
.OrderBy(i => i.Name);
}
public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
{
return itemCollection
.Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
.Select(g => GetGlobalItemName(g));
}
public string GetGlobalItemName(GlobalItem item)
{
if (item is EdmType)
{
return ((EdmType)item).Name;
}
else
{
return ((EntityContainer)item).Name;
}
}
public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type);
}
public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
}
public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
return returnParamsProperty == null
? edmFunction.ReturnParameter
: ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
}
public bool IsComposable(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
}
public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
{
return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
}
public TypeUsage GetReturnType(EdmFunction edmFunction)
{
var returnParam = GetReturnParameter(edmFunction);
return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
}
public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
{
var returnType = GetReturnType(edmFunction);
return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
}
}
public static void ArgumentNotNull<T>(T arg, string name) where T : class
{
if (arg == null)
{
throw new ArgumentNullException(name);
}
}
#>

Просмотреть файл

@ -0,0 +1,10 @@
// T4 code generation is enabled for model 'C:\temp\Hands-on lab\WebApp\InsuranceAPI_KeyVault\InsuranceAPI\Model1.edmx'.
// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
// is open in the designer.
// If no context and entity classes have been generated, it may be because you created an empty model but
// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
// classes for your model, open the model in the designer, right-click on the designer surface, and
// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
// Item...'.

Просмотреть файл

@ -0,0 +1,9 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

Просмотреть файл

@ -0,0 +1,733 @@
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="InsuranceModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012.Azure" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityType Name="Accident">
<Key>
<PropertyRef Name="ReportNumber" />
</Key>
<Property Name="ReportNumber" Type="int" Nullable="false" />
<Property Name="VehicleId" Type="uniqueidentifier" />
<Property Name="UserId" Type="uniqueidentifier" />
<Property Name="Description" Type="nvarchar(max)" />
<Property Name="Location" Type="varchar" MaxLength="50" />
<Property Name="Date" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="DeleteDate" Type="datetime" />
</EntityType>
<EntityType Name="Agent">
<Key>
<PropertyRef Name="AgentId" />
</Key>
<Property Name="AgentId" Type="uniqueidentifier" Nullable="false" />
<Property Name="Name" Type="nvarchar" MaxLength="50" />
<Property Name="Phone" Type="nvarchar" MaxLength="50" />
<Property Name="Address" Type="nvarchar" MaxLength="50" />
<Property Name="Email" Type="nvarchar" MaxLength="50" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
</EntityType>
<EntityType Name="Claim">
<Key>
<PropertyRef Name="ClaimId" />
</Key>
<Property Name="ClaimId" Type="uniqueidentifier" Nullable="false" />
<Property Name="AccidentId" Type="uniqueidentifier" />
<Property Name="Status" Type="nvarchar" MaxLength="50" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
</EntityType>
<EntityType Name="Order">
<Key>
<PropertyRef Name="OrderId" />
</Key>
<Property Name="OrderId" Type="uniqueidentifier" Nullable="false" />
<Property Name="PolicyId" Type="uniqueidentifier" />
<Property Name="UserId" Type="uniqueidentifier" />
<Property Name="CreditCardNumber" Type="nvarchar" MaxLength="50" />
<Property Name="Amount" Type="decimal" Precision="18" Scale="2" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
</EntityType>
<EntityType Name="Participant">
<Key>
<PropertyRef Name="ReportNumber" />
<PropertyRef Name="UserId" />
</Key>
<Property Name="ReportNumber" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="UserId" Type="uniqueidentifier" Nullable="false" />
<Property Name="DamageAmount" Type="decimal" Precision="18" Scale="2" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
</EntityType>
<EntityType Name="Policy">
<Key>
<PropertyRef Name="PolicyId" />
<PropertyRef Name="UserId" />
</Key>
<Property Name="PolicyId" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="UserId" Type="uniqueidentifier" Nullable="false" />
<Property Name="LimitAmount" Type="decimal" Precision="18" Scale="2" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
</EntityType>
<EntityType Name="User">
<Key>
<PropertyRef Name="UserId" />
</Key>
<Property Name="UserId" Type="uniqueidentifier" Nullable="false" />
<Property Name="FirstName" Type="nvarchar" MaxLength="50" />
<Property Name="LastName" Type="nvarchar" MaxLength="50" />
<Property Name="Address" Type="nvarchar" MaxLength="50" />
<Property Name="City" Type="nvarchar" MaxLength="50" />
<Property Name="State" Type="nvarchar" MaxLength="50" />
<Property Name="Zip" Type="nvarchar" MaxLength="50" />
<Property Name="Dob" Type="datetime" />
<Property Name="SSN" Type="nvarchar" MaxLength="50" />
<Property Name="Gender" Type="char" MaxLength="10" />
<Property Name="Email" Type="nvarchar" MaxLength="50" />
<Property Name="Data" Type="nvarchar" MaxLength="50" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
<Property Name="SSN_Encrypted" Type="varbinary" MaxLength="128" />
</EntityType>
<EntityType Name="UserVehicle">
<Key>
<PropertyRef Name="UserId" />
<PropertyRef Name="VehicleId" />
</Key>
<Property Name="UserId" Type="uniqueidentifier" Nullable="false" />
<Property Name="VehicleId" Type="uniqueidentifier" Nullable="false" />
<Property Name="IsActive" Type="bit" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
</EntityType>
<EntityType Name="Vehicle">
<Key>
<PropertyRef Name="VehicleId" />
</Key>
<Property Name="VehicleId" Type="uniqueidentifier" Nullable="false" />
<Property Name="VIN" Type="nvarchar" MaxLength="50" />
<Property Name="License" Type="nvarchar" MaxLength="50" />
<Property Name="Make" Type="nvarchar" MaxLength="50" />
<Property Name="Model" Type="nvarchar" MaxLength="50" />
<Property Name="Year" Type="int" />
<Property Name="Value" Type="decimal" Precision="18" Scale="2" />
<Property Name="PurchaseDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="DeleteDate" Type="datetime" />
</EntityType>
<!--Errors Found During Generation:
warning 6002: The table/view 'Insurance.dbo.vAgentUser' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.-->
<EntityType Name="vAgentUser">
<Key>
<PropertyRef Name="UserId" />
</Key>
<Property Name="UserId" Type="uniqueidentifier" Nullable="false" />
<Property Name="LastName" Type="nvarchar" MaxLength="50" />
<Property Name="Address" Type="nvarchar" MaxLength="50" />
<Property Name="FirstName" Type="nvarchar" MaxLength="50" />
<Property Name="City" Type="nvarchar" MaxLength="50" />
<Property Name="State" Type="nvarchar" MaxLength="50" />
<Property Name="Zip" Type="nvarchar" MaxLength="50" />
<Property Name="Dob" Type="datetime" />
<Property Name="SSN" Type="nvarchar" MaxLength="50" />
<Property Name="Gender" Type="char" MaxLength="10" />
<Property Name="Email" Type="nvarchar" MaxLength="50" />
<Property Name="Data" Type="nvarchar" MaxLength="50" />
<Property Name="ModifyDate" Type="datetime" />
<Property Name="CreateDate" Type="datetime" />
</EntityType>
<Association Name="FK_Accident_User">
<End Role="User" Type="Self.User" Multiplicity="0..1" />
<End Role="Accident" Type="Self.Accident" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Accident">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Accident_Vehicle">
<End Role="Vehicle" Type="Self.Vehicle" Multiplicity="0..1" />
<End Role="Accident" Type="Self.Accident" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Vehicle">
<PropertyRef Name="VehicleId" />
</Principal>
<Dependent Role="Accident">
<PropertyRef Name="VehicleId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Order_User">
<End Role="User" Type="Self.User" Multiplicity="0..1" />
<End Role="Order" Type="Self.Order" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Order">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Participant_User">
<End Role="User" Type="Self.User" Multiplicity="1" />
<End Role="Participant" Type="Self.Participant" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Participant">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Policy_User">
<End Role="User" Type="Self.User" Multiplicity="1" />
<End Role="Policy" Type="Self.Policy" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Policy">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_UserVehicle_User">
<End Role="User" Type="Self.User" Multiplicity="1" />
<End Role="UserVehicle" Type="Self.UserVehicle" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="UserVehicle">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_UserVehicle_Vehicle">
<End Role="Vehicle" Type="Self.Vehicle" Multiplicity="1" />
<End Role="UserVehicle" Type="Self.UserVehicle" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Vehicle">
<PropertyRef Name="VehicleId" />
</Principal>
<Dependent Role="UserVehicle">
<PropertyRef Name="VehicleId" />
</Dependent>
</ReferentialConstraint>
</Association>
<EntityContainer Name="InsuranceModelStoreContainer">
<EntitySet Name="Accident" EntityType="Self.Accident" Schema="dbo" store:Type="Tables" />
<EntitySet Name="Agent" EntityType="Self.Agent" Schema="dbo" store:Type="Tables" />
<EntitySet Name="Claim" EntityType="Self.Claim" Schema="dbo" store:Type="Tables" />
<EntitySet Name="Order" EntityType="Self.Order" Schema="dbo" store:Type="Tables" />
<EntitySet Name="Participant" EntityType="Self.Participant" Schema="dbo" store:Type="Tables" />
<EntitySet Name="Policy" EntityType="Self.Policy" Schema="dbo" store:Type="Tables" />
<EntitySet Name="User" EntityType="Self.User" Schema="dbo" store:Type="Tables" />
<EntitySet Name="UserVehicle" EntityType="Self.UserVehicle" Schema="dbo" store:Type="Tables" />
<EntitySet Name="Vehicle" EntityType="Self.Vehicle" Schema="dbo" store:Type="Tables" />
<EntitySet Name="vAgentUser" EntityType="Self.vAgentUser" store:Type="Views" store:Schema="dbo">
<DefiningQuery>SELECT
[vAgentUser].[UserId] AS [UserId],
[vAgentUser].[LastName] AS [LastName],
[vAgentUser].[Address] AS [Address],
[vAgentUser].[FirstName] AS [FirstName],
[vAgentUser].[City] AS [City],
[vAgentUser].[State] AS [State],
[vAgentUser].[Zip] AS [Zip],
[vAgentUser].[Dob] AS [Dob],
[vAgentUser].[SSN] AS [SSN],
[vAgentUser].[Gender] AS [Gender],
[vAgentUser].[Email] AS [Email],
[vAgentUser].[Data] AS [Data],
[vAgentUser].[ModifyDate] AS [ModifyDate],
[vAgentUser].[CreateDate] AS [CreateDate]
FROM [dbo].[vAgentUser] AS [vAgentUser]</DefiningQuery>
</EntitySet>
<AssociationSet Name="FK_Accident_User" Association="Self.FK_Accident_User">
<End Role="User" EntitySet="User" />
<End Role="Accident" EntitySet="Accident" />
</AssociationSet>
<AssociationSet Name="FK_Accident_Vehicle" Association="Self.FK_Accident_Vehicle">
<End Role="Vehicle" EntitySet="Vehicle" />
<End Role="Accident" EntitySet="Accident" />
</AssociationSet>
<AssociationSet Name="FK_Order_User" Association="Self.FK_Order_User">
<End Role="User" EntitySet="User" />
<End Role="Order" EntitySet="Order" />
</AssociationSet>
<AssociationSet Name="FK_Participant_User" Association="Self.FK_Participant_User">
<End Role="User" EntitySet="User" />
<End Role="Participant" EntitySet="Participant" />
</AssociationSet>
<AssociationSet Name="FK_Policy_User" Association="Self.FK_Policy_User">
<End Role="User" EntitySet="User" />
<End Role="Policy" EntitySet="Policy" />
</AssociationSet>
<AssociationSet Name="FK_UserVehicle_User" Association="Self.FK_UserVehicle_User">
<End Role="User" EntitySet="User" />
<End Role="UserVehicle" EntitySet="UserVehicle" />
</AssociationSet>
<AssociationSet Name="FK_UserVehicle_Vehicle" Association="Self.FK_UserVehicle_Vehicle">
<End Role="Vehicle" EntitySet="Vehicle" />
<End Role="UserVehicle" EntitySet="UserVehicle" />
</AssociationSet>
</EntityContainer>
</Schema></edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="InsuranceModel" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityType Name="Claim">
<Key>
<PropertyRef Name="ClaimId" />
</Key>
<Property Name="ClaimId" Type="Guid" Nullable="false" />
<Property Name="AccidentId" Type="Guid" />
<Property Name="Status" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
</EntityType>
<EntityType Name="Order">
<Key>
<PropertyRef Name="OrderId" />
</Key>
<Property Name="OrderId" Type="Guid" Nullable="false" />
<Property Name="PolicyId" Type="Guid" />
<Property Name="UserId" Type="Guid" />
<Property Name="CreditCardNumber" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Amount" Type="Decimal" Precision="18" Scale="2" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
<NavigationProperty Name="User" Relationship="InsuranceModel.FK_Order_User" FromRole="Order" ToRole="User" />
</EntityType>
<EntityType Name="User">
<Key>
<PropertyRef Name="UserId" />
</Key>
<Property Name="UserId" Type="Guid" Nullable="false" />
<Property Name="FirstName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="LastName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Address" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="City" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="State" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Zip" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Dob" Type="DateTime" Precision="3" />
<Property Name="SSN" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Gender" Type="String" MaxLength="10" FixedLength="true" Unicode="false" />
<Property Name="Email" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
<NavigationProperty Name="Accidents" Relationship="InsuranceModel.FK_Accident_User" FromRole="User" ToRole="Accident" />
<NavigationProperty Name="Orders" Relationship="InsuranceModel.FK_Order_User" FromRole="User" ToRole="Order" />
<NavigationProperty Name="Participants" Relationship="InsuranceModel.FK_Participant_User" FromRole="User" ToRole="Participant" />
<NavigationProperty Name="Policies" Relationship="InsuranceModel.FK_Policy_User" FromRole="User" ToRole="Policy" />
<NavigationProperty Name="UserVehicles" Relationship="InsuranceModel.FK_UserVehicle_User" FromRole="User" ToRole="UserVehicle" />
</EntityType>
<EntityType Name="UserVehicle">
<Key>
<PropertyRef Name="UserId" />
<PropertyRef Name="VehicleId" />
</Key>
<Property Name="UserId" Type="Guid" Nullable="false" />
<Property Name="VehicleId" Type="Guid" Nullable="false" />
<Property Name="IsActive" Type="Boolean" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
<NavigationProperty Name="User" Relationship="InsuranceModel.FK_UserVehicle_User" FromRole="UserVehicle" ToRole="User" />
<NavigationProperty Name="Vehicle" Relationship="InsuranceModel.FK_UserVehicle_Vehicle" FromRole="UserVehicle" ToRole="Vehicle" />
</EntityType>
<EntityType Name="Vehicle">
<Key>
<PropertyRef Name="VehicleId" />
</Key>
<Property Name="VehicleId" Type="Guid" Nullable="false" />
<Property Name="VIN" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="License" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Make" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Model" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Year" Type="Int32" />
<Property Name="Value" Type="Decimal" Precision="18" Scale="2" />
<Property Name="PurchaseDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="DeleteDate" Type="DateTime" Precision="3" />
<NavigationProperty Name="Accidents" Relationship="InsuranceModel.FK_Accident_Vehicle" FromRole="Vehicle" ToRole="Accident" />
<NavigationProperty Name="UserVehicles" Relationship="InsuranceModel.FK_UserVehicle_Vehicle" FromRole="Vehicle" ToRole="UserVehicle" />
</EntityType>
<EntityContainer Name="InsuranceEntities" annotation:LazyLoadingEnabled="true">
<EntitySet Name="Claims" EntityType="Self.Claim" />
<EntitySet Name="Orders" EntityType="Self.Order" />
<EntitySet Name="Users" EntityType="Self.User" />
<EntitySet Name="UserVehicles" EntityType="Self.UserVehicle" />
<EntitySet Name="Vehicles" EntityType="Self.Vehicle" />
<EntitySet Name="Accidents" EntityType="InsuranceModel.Accident" />
<EntitySet Name="Agents" EntityType="InsuranceModel.Agent" />
<EntitySet Name="Participants" EntityType="InsuranceModel.Participant" />
<EntitySet Name="Policies" EntityType="InsuranceModel.Policy" />
<EntitySet Name="vAgentUsers" EntityType="InsuranceModel.vAgentUser" />
<AssociationSet Name="FK_Accident_User" Association="InsuranceModel.FK_Accident_User">
<End Role="User" EntitySet="Users" />
<End Role="Accident" EntitySet="Accidents" />
</AssociationSet>
<AssociationSet Name="FK_Accident_Vehicle" Association="InsuranceModel.FK_Accident_Vehicle">
<End Role="Vehicle" EntitySet="Vehicles" />
<End Role="Accident" EntitySet="Accidents" />
</AssociationSet>
<AssociationSet Name="FK_Order_User" Association="InsuranceModel.FK_Order_User">
<End Role="User" EntitySet="Users" />
<End Role="Order" EntitySet="Orders" />
</AssociationSet>
<AssociationSet Name="FK_Participant_User" Association="InsuranceModel.FK_Participant_User">
<End Role="User" EntitySet="Users" />
<End Role="Participant" EntitySet="Participants" />
</AssociationSet>
<AssociationSet Name="FK_Policy_User" Association="InsuranceModel.FK_Policy_User">
<End Role="User" EntitySet="Users" />
<End Role="Policy" EntitySet="Policies" />
</AssociationSet>
<AssociationSet Name="FK_UserVehicle_User" Association="InsuranceModel.FK_UserVehicle_User">
<End Role="User" EntitySet="Users" />
<End Role="UserVehicle" EntitySet="UserVehicles" />
</AssociationSet>
<AssociationSet Name="FK_UserVehicle_Vehicle" Association="InsuranceModel.FK_UserVehicle_Vehicle">
<End Role="Vehicle" EntitySet="Vehicles" />
<End Role="UserVehicle" EntitySet="UserVehicles" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Accident">
<Key>
<PropertyRef Name="ReportNumber" />
</Key>
<Property Name="ReportNumber" Type="Int32" Nullable="false" />
<Property Name="VehicleId" Type="Guid" />
<Property Name="UserId" Type="Guid" />
<Property Name="Description" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
<Property Name="Location" Type="String" MaxLength="50" FixedLength="false" Unicode="false" />
<Property Name="Date" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="DeleteDate" Type="DateTime" Precision="3" />
<NavigationProperty Name="User" Relationship="InsuranceModel.FK_Accident_User" FromRole="Accident" ToRole="User" />
<NavigationProperty Name="Vehicle" Relationship="InsuranceModel.FK_Accident_Vehicle" FromRole="Accident" ToRole="Vehicle" />
</EntityType>
<EntityType Name="Agent">
<Key>
<PropertyRef Name="AgentId" />
</Key>
<Property Name="AgentId" Type="Guid" Nullable="false" />
<Property Name="Name" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Phone" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Address" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Email" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
</EntityType>
<EntityType Name="Participant">
<Key>
<PropertyRef Name="ReportNumber" />
<PropertyRef Name="UserId" />
</Key>
<Property Name="ReportNumber" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="UserId" Type="Guid" Nullable="false" />
<Property Name="DamageAmount" Type="Decimal" Precision="18" Scale="2" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
<NavigationProperty Name="User" Relationship="InsuranceModel.FK_Participant_User" FromRole="Participant" ToRole="User" />
</EntityType>
<EntityType Name="Policy">
<Key>
<PropertyRef Name="PolicyId" />
<PropertyRef Name="UserId" />
</Key>
<Property Name="PolicyId" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="UserId" Type="Guid" Nullable="false" />
<Property Name="LimitAmount" Type="Decimal" Precision="18" Scale="2" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
<NavigationProperty Name="User" Relationship="InsuranceModel.FK_Policy_User" FromRole="Policy" ToRole="User" />
</EntityType>
<EntityType Name="vAgentUser">
<Key>
<PropertyRef Name="UserId" />
</Key>
<Property Name="UserId" Type="Guid" Nullable="false" />
<Property Name="LastName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Address" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="FirstName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="City" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="State" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Zip" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Dob" Type="DateTime" Precision="3" />
<Property Name="SSN" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Gender" Type="String" MaxLength="10" FixedLength="true" Unicode="false" />
<Property Name="Email" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Data" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="ModifyDate" Type="DateTime" Precision="3" />
<Property Name="CreateDate" Type="DateTime" Precision="3" />
</EntityType>
<Association Name="FK_Accident_User">
<End Type="InsuranceModel.User" Role="User" Multiplicity="0..1" />
<End Type="InsuranceModel.Accident" Role="Accident" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Accident">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Accident_Vehicle">
<End Type="InsuranceModel.Vehicle" Role="Vehicle" Multiplicity="0..1" />
<End Type="InsuranceModel.Accident" Role="Accident" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Vehicle">
<PropertyRef Name="VehicleId" />
</Principal>
<Dependent Role="Accident">
<PropertyRef Name="VehicleId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Order_User">
<End Type="InsuranceModel.User" Role="User" Multiplicity="0..1" />
<End Type="InsuranceModel.Order" Role="Order" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Order">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Participant_User">
<End Type="InsuranceModel.User" Role="User" Multiplicity="1" />
<End Type="InsuranceModel.Participant" Role="Participant" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Participant">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Policy_User">
<End Type="InsuranceModel.User" Role="User" Multiplicity="1" />
<End Type="InsuranceModel.Policy" Role="Policy" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="Policy">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_UserVehicle_User">
<End Type="InsuranceModel.User" Role="User" Multiplicity="1" />
<End Type="InsuranceModel.UserVehicle" Role="UserVehicle" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="User">
<PropertyRef Name="UserId" />
</Principal>
<Dependent Role="UserVehicle">
<PropertyRef Name="UserId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_UserVehicle_Vehicle">
<End Type="InsuranceModel.Vehicle" Role="Vehicle" Multiplicity="1" />
<End Type="InsuranceModel.UserVehicle" Role="UserVehicle" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Vehicle">
<PropertyRef Name="VehicleId" />
</Principal>
<Dependent Role="UserVehicle">
<PropertyRef Name="VehicleId" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
<EntityContainerMapping StorageEntityContainer="InsuranceModelStoreContainer" CdmEntityContainer="InsuranceEntities">
<EntitySetMapping Name="Claims">
<EntityTypeMapping TypeName="InsuranceModel.Claim">
<MappingFragment StoreEntitySet="Claim">
<ScalarProperty Name="ClaimId" ColumnName="ClaimId" />
<ScalarProperty Name="AccidentId" ColumnName="AccidentId" />
<ScalarProperty Name="Status" ColumnName="Status" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Orders">
<EntityTypeMapping TypeName="InsuranceModel.Order">
<MappingFragment StoreEntitySet="Order">
<ScalarProperty Name="OrderId" ColumnName="OrderId" />
<ScalarProperty Name="PolicyId" ColumnName="PolicyId" />
<ScalarProperty Name="UserId" ColumnName="UserId" />
<ScalarProperty Name="CreditCardNumber" ColumnName="CreditCardNumber" />
<ScalarProperty Name="Amount" ColumnName="Amount" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Users">
<EntityTypeMapping TypeName="InsuranceModel.User">
<MappingFragment StoreEntitySet="User">
<ScalarProperty Name="UserId" ColumnName="UserId" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
<ScalarProperty Name="LastName" ColumnName="LastName" />
<ScalarProperty Name="Address" ColumnName="Address" />
<ScalarProperty Name="City" ColumnName="City" />
<ScalarProperty Name="State" ColumnName="State" />
<ScalarProperty Name="Zip" ColumnName="Zip" />
<ScalarProperty Name="Dob" ColumnName="Dob" />
<ScalarProperty Name="SSN" ColumnName="SSN" />
<ScalarProperty Name="Gender" ColumnName="Gender" />
<ScalarProperty Name="Email" ColumnName="Email" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="UserVehicles">
<EntityTypeMapping TypeName="InsuranceModel.UserVehicle">
<MappingFragment StoreEntitySet="UserVehicle">
<ScalarProperty Name="UserId" ColumnName="UserId" />
<ScalarProperty Name="VehicleId" ColumnName="VehicleId" />
<ScalarProperty Name="IsActive" ColumnName="IsActive" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Vehicles">
<EntityTypeMapping TypeName="InsuranceModel.Vehicle">
<MappingFragment StoreEntitySet="Vehicle">
<ScalarProperty Name="VehicleId" ColumnName="VehicleId" />
<ScalarProperty Name="VIN" ColumnName="VIN" />
<ScalarProperty Name="License" ColumnName="License" />
<ScalarProperty Name="Make" ColumnName="Make" />
<ScalarProperty Name="Model" ColumnName="Model" />
<ScalarProperty Name="Year" ColumnName="Year" />
<ScalarProperty Name="Value" ColumnName="Value" />
<ScalarProperty Name="PurchaseDate" ColumnName="PurchaseDate" />
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="DeleteDate" ColumnName="DeleteDate" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Accidents">
<EntityTypeMapping TypeName="InsuranceModel.Accident">
<MappingFragment StoreEntitySet="Accident">
<ScalarProperty Name="DeleteDate" ColumnName="DeleteDate" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
<ScalarProperty Name="Date" ColumnName="Date" />
<ScalarProperty Name="Location" ColumnName="Location" />
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="UserId" ColumnName="UserId" />
<ScalarProperty Name="VehicleId" ColumnName="VehicleId" />
<ScalarProperty Name="ReportNumber" ColumnName="ReportNumber" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Agents">
<EntityTypeMapping TypeName="InsuranceModel.Agent">
<MappingFragment StoreEntitySet="Agent">
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="Email" ColumnName="Email" />
<ScalarProperty Name="Address" ColumnName="Address" />
<ScalarProperty Name="Phone" ColumnName="Phone" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="AgentId" ColumnName="AgentId" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Participants">
<EntityTypeMapping TypeName="InsuranceModel.Participant">
<MappingFragment StoreEntitySet="Participant">
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="DamageAmount" ColumnName="DamageAmount" />
<ScalarProperty Name="UserId" ColumnName="UserId" />
<ScalarProperty Name="ReportNumber" ColumnName="ReportNumber" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Policies">
<EntityTypeMapping TypeName="InsuranceModel.Policy">
<MappingFragment StoreEntitySet="Policy">
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="LimitAmount" ColumnName="LimitAmount" />
<ScalarProperty Name="UserId" ColumnName="UserId" />
<ScalarProperty Name="PolicyId" ColumnName="PolicyId" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="vAgentUsers">
<EntityTypeMapping TypeName="InsuranceModel.vAgentUser">
<MappingFragment StoreEntitySet="vAgentUser">
<ScalarProperty Name="CreateDate" ColumnName="CreateDate" />
<ScalarProperty Name="ModifyDate" ColumnName="ModifyDate" />
<ScalarProperty Name="Data" ColumnName="Data" />
<ScalarProperty Name="Email" ColumnName="Email" />
<ScalarProperty Name="Gender" ColumnName="Gender" />
<ScalarProperty Name="SSN" ColumnName="SSN" />
<ScalarProperty Name="Dob" ColumnName="Dob" />
<ScalarProperty Name="Zip" ColumnName="Zip" />
<ScalarProperty Name="State" ColumnName="State" />
<ScalarProperty Name="City" ColumnName="City" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
<ScalarProperty Name="Address" ColumnName="Address" />
<ScalarProperty Name="LastName" ColumnName="LastName" />
<ScalarProperty Name="UserId" ColumnName="UserId" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
<Connection>
<DesignerInfoPropertySet>
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
</DesignerInfoPropertySet>
</Connection>
<Options>
<DesignerInfoPropertySet>
<DesignerProperty Name="ValidateOnBuild" Value="true" />
<DesignerProperty Name="EnablePluralization" Value="true" />
<DesignerProperty Name="IncludeForeignKeysInModel" Value="true" />
<DesignerProperty Name="UseLegacyProvider" Value="false" />
<DesignerProperty Name="CodeGenerationStrategy" Value="None" />
</DesignerInfoPropertySet>
</Options>
<!-- Diagram content (shape and connector positions) -->
<Diagrams></Diagrams>
</Designer>
</edmx:Edmx>

Просмотреть файл

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<edmx:Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
<!-- Diagram content (shape and connector positions) -->
<edmx:Diagrams>
<Diagram DiagramId="47b9343692fa4fb691d42865645aec2f" Name="Diagram1">
<EntityTypeShape EntityType="InsuranceModel.Claim" Width="1.5" PointX="0.75" PointY="0.75" IsExpanded="true" />
<EntityTypeShape EntityType="InsuranceModel.Order" Width="1.5" PointX="2.75" PointY="0.75" IsExpanded="true" />
<EntityTypeShape EntityType="InsuranceModel.User" Width="1.5" PointX="4.75" PointY="0.75" IsExpanded="true" />
<EntityTypeShape EntityType="InsuranceModel.UserVehicle" Width="1.5" PointX="0.75" PointY="4.75" IsExpanded="true" />
<EntityTypeShape EntityType="InsuranceModel.Vehicle" Width="1.5" PointX="2.75" PointY="5.75" IsExpanded="true" />
<EntityTypeShape EntityType="InsuranceModel.Accident" Width="1.5" PointX="5.375" PointY="5.75" />
<EntityTypeShape EntityType="InsuranceModel.Agent" Width="1.5" PointX="7.375" PointY="0.75" />
<EntityTypeShape EntityType="InsuranceModel.Participant" Width="1.5" PointX="7.375" PointY="4.75" />
<EntityTypeShape EntityType="InsuranceModel.Policy" Width="1.5" PointX="7.375" PointY="7.75" />
<EntityTypeShape EntityType="InsuranceModel.vAgentUser" Width="1.5" PointX="10.5" PointY="0.75" />
<AssociationConnector Association="InsuranceModel.FK_Accident_User" />
<AssociationConnector Association="InsuranceModel.FK_Accident_Vehicle" />
<AssociationConnector Association="InsuranceModel.FK_Order_User" />
<AssociationConnector Association="InsuranceModel.FK_Participant_User" />
<AssociationConnector Association="InsuranceModel.FK_Policy_User" />
<AssociationConnector Association="InsuranceModel.FK_UserVehicle_User" />
<AssociationConnector Association="InsuranceModel.FK_UserVehicle_Vehicle" />
</Diagram>
</edmx:Diagrams>
</edmx:Designer>
</edmx:Edmx>

Просмотреть файл

@ -0,0 +1,733 @@
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
output extension=".cs"#><#
const string inputFile = @"Model1.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var fileManager = EntityFrameworkTemplateFileManager.Create(this);
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
{
return string.Empty;
}
WriteHeader(codeStringGenerator, fileManager);
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
fileManager.StartNewFile(entity.Name + ".cs");
BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
<#=codeStringGenerator.EntityClassOpening(entity)#>
{
<#
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
var complexProperties = typeMapper.GetComplexProperties(entity);
if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
{
#>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public <#=code.Escape(entity)#>()
{
<#
foreach (var edmProperty in propertiesWithDefaultValues)
{
#>
this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
<#
}
foreach (var navigationProperty in collectionNavigationProperties)
{
#>
this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
<#
}
foreach (var complexProperty in complexProperties)
{
#>
this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
<#
}
#>
}
<#
}
var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{
#>
<#=codeStringGenerator.Property(edmProperty)#>
<#
}
}
if (complexProperties.Any())
{
#>
<#
foreach(var complexProperty in complexProperties)
{
#>
<#=codeStringGenerator.Property(complexProperty)#>
<#
}
}
var navigationProperties = typeMapper.GetNavigationProperties(entity);
if (navigationProperties.Any())
{
#>
<#
foreach (var navigationProperty in navigationProperties)
{
if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
{
#>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
<#
}
#>
<#=codeStringGenerator.NavigationProperty(navigationProperty)#>
<#
}
}
#>
}
<#
EndNamespace(code);
}
foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
{
fileManager.StartNewFile(complex.Name + ".cs");
BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
{
<#
var complexProperties = typeMapper.GetComplexProperties(complex);
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
if (propertiesWithDefaultValues.Any() || complexProperties.Any())
{
#>
public <#=code.Escape(complex)#>()
{
<#
foreach (var edmProperty in propertiesWithDefaultValues)
{
#>
this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
<#
}
foreach (var complexProperty in complexProperties)
{
#>
this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
<#
}
#>
}
<#
}
var simpleProperties = typeMapper.GetSimpleProperties(complex);
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
<#=codeStringGenerator.Property(edmProperty)#>
<#
}
}
if (complexProperties.Any())
{
#>
<#
foreach(var edmProperty in complexProperties)
{
#>
<#=codeStringGenerator.Property(edmProperty)#>
<#
}
}
#>
}
<#
EndNamespace(code);
}
foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
{
fileManager.StartNewFile(enumType.Name + ".cs");
BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
<#
if (typeMapper.EnumIsFlags(enumType))
{
#>
[Flags]
<#
}
#>
<#=codeStringGenerator.EnumOpening(enumType)#>
{
<#
var foundOne = false;
foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
{
foundOne = true;
#>
<#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
<#
}
if (foundOne)
{
this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
}
#>
}
<#
EndNamespace(code);
}
fileManager.Process();
#>
<#+
public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
{
fileManager.StartHeader();
#>
//------------------------------------------------------------------------------
// <auto-generated>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
//
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
// </auto-generated>
//------------------------------------------------------------------------------
<#=codeStringGenerator.UsingDirectives(inHeader: true)#>
<#+
fileManager.EndBlock();
}
public void BeginNamespace(CodeGenerationTools code)
{
var codeNamespace = code.VsNamespaceSuggestion();
if (!String.IsNullOrEmpty(codeNamespace))
{
#>
namespace <#=code.EscapeNamespace(codeNamespace)#>
{
<#+
PushIndent(" ");
}
}
public void EndNamespace(CodeGenerationTools code)
{
if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
{
PopIndent();
#>
}
<#+
}
}
public const string TemplateId = "CSharp_DbContext_Types_EF6";
public class CodeStringGenerator
{
private readonly CodeGenerationTools _code;
private readonly TypeMapper _typeMapper;
private readonly MetadataTools _ef;
public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(typeMapper, "typeMapper");
ArgumentNotNull(ef, "ef");
_code = code;
_typeMapper = typeMapper;
_ef = ef;
}
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
public string AccessibilityAndVirtual(string accessibility)
{
return accessibility + (accessibility != "private" ? " virtual" : "");
}
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
public string EnumOpening(SimpleType enumType)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} enum {1} : {2}",
Accessibility.ForType(enumType),
_code.Escape(enumType),
_code.Escape(_typeMapper.UnderlyingClrType(enumType)));
}
public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
{
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
{
var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
}
}
public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"{0} IQueryable<{1}> {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
_code.Escape(edmFunction),
string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
}
public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
edmFunction.NamespaceName,
edmFunction.Name,
string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
_code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
}
public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
if (includeMergeOption)
{
paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
}
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
_code.Escape(edmFunction),
paramList);
}
public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
if (includeMergeOption)
{
callParams = ", mergeOption" + callParams;
}
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
edmFunction.Name,
callParams);
}
public string DbSet(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} virtual DbSet<{1}> {2} {{ get; set; }}",
Accessibility.ForReadOnlyProperty(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType),
_code.Escape(entitySet));
}
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"{2}",
inHeader ? Environment.NewLine : "",
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
}
public class TypeMapper
{
private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
private readonly System.Collections.IList _errors;
private readonly CodeGenerationTools _code;
private readonly MetadataTools _ef;
public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(ef, "ef");
ArgumentNotNull(errors, "errors");
_code = code;
_ef = ef;
_errors = errors;
}
public static string FixNamespaces(string typeName)
{
return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
}
public string GetTypeName(TypeUsage typeUsage)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
}
public string GetTypeName(EdmType edmType)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: null);
}
public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
}
public string GetTypeName(EdmType edmType, string modelNamespace)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
}
public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
{
if (edmType == null)
{
return null;
}
var collectionType = edmType as CollectionType;
if (collectionType != null)
{
return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
}
var typeName = _code.Escape(edmType.MetadataProperties
.Where(p => p.Name == ExternalTypeNameAttributeName)
.Select(p => (string)p.Value)
.FirstOrDefault())
?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
_code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
_code.Escape(edmType));
if (edmType is StructuralType)
{
return typeName;
}
if (edmType is SimpleType)
{
var clrType = UnderlyingClrType(edmType);
if (!IsEnumType(edmType))
{
typeName = _code.Escape(clrType);
}
typeName = FixNamespaces(typeName);
return clrType.IsValueType && isNullable == true ?
String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
typeName;
}
throw new ArgumentException("edmType");
}
public Type UnderlyingClrType(EdmType edmType)
{
ArgumentNotNull(edmType, "edmType");
var primitiveType = edmType as PrimitiveType;
if (primitiveType != null)
{
return primitiveType.ClrEquivalentType;
}
if (IsEnumType(edmType))
{
return GetEnumUnderlyingType(edmType).ClrEquivalentType;
}
return typeof(object);
}
public object GetEnumMemberValue(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var valueProperty = enumMember.GetType().GetProperty("Value");
return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
}
public string GetEnumMemberName(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var nameProperty = enumMember.GetType().GetProperty("Name");
return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
}
public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var membersProperty = enumType.GetType().GetProperty("Members");
return membersProperty != null
? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
: Enumerable.Empty<MetadataItem>();
}
public bool EnumIsFlags(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
}
public bool IsEnumType(GlobalItem edmType)
{
ArgumentNotNull(edmType, "edmType");
return edmType.GetType().Name == "EnumType";
}
public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
}
public string CreateLiteral(object value)
{
if (value == null || value.GetType() != typeof(TimeSpan))
{
return _code.CreateLiteral(value);
}
return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
}
public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
{
ArgumentNotNull(types, "types");
ArgumentNotNull(sourceFile, "sourceFile");
var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
if (types.Any(item => !hash.Add(item)))
{
_errors.Add(
new CompilerError(sourceFile, -1, -1, "6023",
String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
return false;
}
return true;
}
public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
{
return GetItemsToGenerate<SimpleType>(itemCollection)
.Where(e => IsEnumType(e));
}
public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
{
return itemCollection
.OfType<T>()
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
.OrderBy(i => i.Name);
}
public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
{
return itemCollection
.Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
.Select(g => GetGlobalItemName(g));
}
public string GetGlobalItemName(GlobalItem item)
{
if (item is EdmType)
{
return ((EdmType)item).Name;
}
else
{
return ((EntityContainer)item).Name;
}
}
public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type);
}
public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
}
public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
return returnParamsProperty == null
? edmFunction.ReturnParameter
: ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
}
public bool IsComposable(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
}
public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
{
return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
}
public TypeUsage GetReturnType(EdmFunction edmFunction)
{
var returnParam = GetReturnParameter(edmFunction);
return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
}
public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
{
var returnType = GetReturnType(edmFunction);
return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
}
}
public static void ArgumentNotNull<T>(T arg, string name) where T : class
{
if (arg == null)
{
throw new ArgumentNullException(name);
}
}
#>

Просмотреть файл

@ -0,0 +1,27 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InsuranceAPI
{
using System;
using System.Collections.Generic;
public partial class Order
{
public System.Guid OrderId { get; set; }
public Nullable<System.Guid> PolicyId { get; set; }
public Nullable<System.Guid> UserId { get; set; }
public string CreditCardNumber { get; set; }
public Nullable<decimal> Amount { get; set; }
public Nullable<System.DateTime> ModifyDate { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
public virtual User User { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InsuranceAPI
{
using System;
using System.Collections.Generic;
public partial class Participant
{
public string ReportNumber { get; set; }
public System.Guid UserId { get; set; }
public Nullable<decimal> DamageAmount { get; set; }
public Nullable<System.DateTime> ModifyDate { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
public virtual User User { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace InsuranceAPI
{
using System;
using System.Collections.Generic;
public partial class Policy
{
public string PolicyId { get; set; }
public System.Guid UserId { get; set; }
public Nullable<decimal> LimitAmount { get; set; }
public Nullable<System.DateTime> ModifyDate { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
public virtual User User { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("InsuranceAPI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("InsuranceAPI")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5b472859-a12e-435d-bf3b-1e473d72e29c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -0,0 +1,219 @@
<!-- IGNORE THE HTML BLOCK BELOW, THE INTERESTING PART IS AFTER IT -->
<h1 align="center">Popper.js</h1>
<p align="center">
<strong>A library used to position poppers in web applications.</strong>
</p>
<p align="center">
<a href="https://travis-ci.org/FezVrasta/popper.js/branches" target="_blank"><img src="https://travis-ci.org/FezVrasta/popper.js.svg?branch=master" alt="Build Status"/></a>
<img src="http://img.badgesize.io/https://unpkg.com/popper.js/dist/popper.min.js?compression=gzip" alt="Stable Release Size"/>
<a href="https://www.bithound.io/github/FezVrasta/popper.js"><img src="https://www.bithound.io/github/FezVrasta/popper.js/badges/score.svg" alt="bitHound Overall Score"></a>
<a href="https://codeclimate.com/github/FezVrasta/popper.js/coverage"><img src="https://codeclimate.com/github/FezVrasta/popper.js/badges/coverage.svg" alt="Istanbul Code Coverage"/></a>
<a href="https://gitter.im/FezVrasta/popper.js" target="_blank"><img src="https://img.shields.io/gitter/room/nwjs/nw.js.svg" alt="Get support or discuss"/></a>
<br />
<a href="https://saucelabs.com/u/popperjs" target="_blank"><img src="https://badges.herokuapp.com/browsers?labels=none&googlechrome=latest&firefox=latest&microsoftedge=latest&iexplore=11,10&safari=latest&iphone=latest" alt="SauceLabs Reports"/></a>
</p>
<img src="https://raw.githubusercontent.com/FezVrasta/popper.js/master/popperjs.png" align="right" width=250 />
<!-- 🚨 HEY! HERE BEGINS THE INTERESTING STUFF 🚨 -->
## Wut? Poppers?
A popper is an element on the screen which "pops out" from the natural flow of your application.
Common examples of poppers are tooltips, popovers and drop-downs.
## So, yet another tooltip library?
Well, basically, **no**.
Popper.js is a **positioning engine**, its purpose is to calculate the position of an element
to make it possible to position it near a given reference element.
The engine is completely modular and most of its features are implemented as **modifiers**
(similar to middlewares or plugins).
The whole code base is written in ES2015 and its features are automatically tested on real browsers thanks to [SauceLabs](https://saucelabs.com/) and [TravisCI](https://travis-ci.org/).
Popper.js has zero dependencies. No jQuery, no LoDash, nothing.
It's used by big companies like [Twitter in Bootstrap v4](https://getbootstrap.com/), [Microsoft in WebClipper](https://github.com/OneNoteDev/WebClipper) and [Atlassian in AtlasKit](https://aui-cdn.atlassian.com/atlaskit/registry/).
### Popper.js
This is the engine, the library that computes and, optionally, applies the styles to
the poppers.
Some of the key points are:
- Position elements keeping them in their original DOM context (doesn't mess with your DOM!);
- Allows to export the computed informations to integrate with React and other view libraries;
- Supports Shadow DOM elements;
- Completely customizable thanks to the modifiers based structure;
Visit our [project page](https://fezvrasta.github.io/popper.js) to see a lot of examples of what you can do with Popper.js!
Find [the documentation here](/docs/_includes/popper-documentation.md).
### Tooltip.js
Since lots of users just need a simple way to integrate powerful tooltips in their projects,
we created **Tooltip.js**.
It's a small library that makes it easy to automatically create tooltips using as engine Popper.js.
Its API is almost identical to the famous tooltip system of Bootstrap, in this way it will be
easy to integrate it in your projects.
The tooltips generated by Tooltip.js are accessible thanks to the `aria` tags.
Find [the documentation here](/docs/_includes/tooltip-documentation.md).
## Installation
Popper.js is available on the following package managers and CDNs:
| Source | |
|:-------|:---------------------------------------------------------------------------------|
| npm | `npm install popper.js --save` |
| yarn | `yarn add popper.js` |
| NuGet | `PM> Install-Package popper.js` |
| Bower | `bower install popper.js --save` |
| unpkg | [`https://unpkg.com/popper.js`](https://unpkg.com/popper.js) |
| cdnjs | [`https://cdnjs.com/libraries/popper.js`](https://cdnjs.com/libraries/popper.js) |
Tooltip.js as well:
| Source | |
|:-------|:---------------------------------------------------------------------------------|
| npm | `npm install tooltip.js --save` |
| yarn | `yarn add tooltip.js` |
| Bower* | `bower install tooltip.js=https://unpkg.com/tooltip.js --save` |
| unpkg | [`https://unpkg.com/tooltip.js`](https://unpkg.com/tooltip.js) |
| cdnjs | [`https://cdnjs.com/libraries/popper.js`](https://cdnjs.com/libraries/popper.js) |
\*: Bower isn't officially supported, it can be used to install Tooltip.js only trough the unpkg.com CDN. This method has the limitation of not being able to define a specific version of the library. Bower and Popper.js suggests to use npm or Yarn for your projects.
For more info, [read the related issue](https://github.com/FezVrasta/popper.js/issues/390).
### Dist targets
Popper.js is currently shipped with 3 targets in mind: UMD, ESM and ESNext.
- UMD - Universal Module Definition: AMD, RequireJS and globals;
- ESM - ES Modules: For webpack/Rollup or browser supporting the spec;
- ESNext: Available in `dist/`, can be used with webpack and `babel-preset-env`;
Make sure to use the right one for your needs. If you want to import it with a `<script>` tag, use UMD.
## Usage
Given an existing popper DOM node, ask Popper.js to position it near its button
```js
var reference = document.querySelector('.my-button');
var popper = document.querySelector('.my-popper');
var anotherPopper = new Popper(
reference,
popper,
{
// popper options here
}
);
```
### Callbacks
Popper.js supports two kinds of callbacks, the `onCreate` callback is called after
the popper has been initalized. The `onUpdate` one is called on any subsequent update.
```js
const reference = document.querySelector('.my-button');
const popper = document.querySelector('.my-popper');
new Popper(reference, popper, {
onCreate: (data) => {
// data is an object containing all the informations computed
// by Popper.js and used to style the popper and its arrow
// The complete description is available in Popper.js documentation
},
onUpdate: (data) => {
// same as `onCreate` but called on subsequent updates
}
});
```
### Writing your own modifiers
Popper.js is based on a "plugin-like" architecture, most of its features are fully encapsulated "modifiers".
A modifier is a function that is called each time Popper.js needs to compute the position of the popper. For this reason, modifiers should be very performant to avoid bottlenecks.
To learn how to create a modifier, [read the modifiers documentation](docs/_includes/popper-documentation.md#modifiers--object)
### React, Vue.js, Angular, AngularJS, Ember.js (etc...) integration
Integrating 3rd party libraries in React or other libraries can be a pain because
they usually alter the DOM and drive the libraries crazy.
Popper.js limits all its DOM modifications inside the `applyStyle` modifier,
you can simply disable it and manually apply the popper coordinates using
your library of choice.
For a comprehensive list of libraries that let you use Popper.js into existing
frameworks, visit the [MENTIONS](/MENTIONS.md) page.
Alternatively, you may even override your own `applyStyles` with your custom one and
integrate Popper.js by yourself!
```js
function applyReactStyle(data) {
// export data in your framework and use its content to apply the style to your popper
};
const reference = document.querySelector('.my-button');
const popper = document.querySelector('.my-popper');
new Popper(reference, popper, {
modifiers: {
applyStyle: { enabled: false },
applyReactStyle: {
enabled: true,
fn: applyReactStyle,
order: 800,
},
},
});
```
### Migration from Popper.js v0
Since the API changed, we prepared some migration instructions to make it easy to upgrade to
Popper.js v1.
https://github.com/FezVrasta/popper.js/issues/62
Feel free to comment inside the issue if you have any questions.
### Performances
Popper.js is very performant. It usually takes 0.5ms to compute a popper's position (on an iMac with 3.5G GHz Intel Core i5).
This means that it will not cause any [jank](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool/anatomy-of-jank), leading to a smooth user experience.
## Notes
### Libraries using Popper.js
The aim of Popper.js is to provide a stable and powerful positioning engine ready to
be used in 3rd party libraries.
Visit the [MENTIONS](/MENTIONS.md) page for an updated list of projects.
### Credits
I want to thank some friends and projects for the work they did:
- [@AndreaScn](https://github.com/AndreaScn) for his work on the GitHub Page and the manual testing he did during the development;
- [@vampolo](https://github.com/vampolo) for the original idea and for the name of the library;
- [Sysdig](https://github.com/Draios) for all the awesome things I learned during these years that made it possible for me to write this library;
- [Tether.js](http://github.hubspot.com/tether/) for having inspired me in writing a positioning library ready for the real world;
- [The Contributors](https://github.com/FezVrasta/popper.js/graphs/contributors) for their much appreciated Pull Requests and bug reports;
- **you** for the star you'll give to this project and for being so awesome to give this project a try 🙂
### Copyright and license
Code and documentation copyright 2016 **Federico Zivolo**. Code released under the [MIT license](LICENSE.md). Docs released under Creative Commons.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше