diff --git a/.ghal.rules.json b/.ghal.rules.json index e2fb084a36e4..40adf91138f2 100644 --- a/.ghal.rules.json +++ b/.ghal.rules.json @@ -2,6 +2,10 @@ "labels": { "product": { "(?i).*": "Source - Docs.ms" + }, + "contentsource": { + "(?i).*master\/aspnetcore\/signalr.*": "SignalR", + "(?i).*master\/aspnetcore\/tutorials\/signalr*.*": "SignalR" } } } diff --git a/.github/ISSUE_TEMPLATE/doc-issue.md b/.github/ISSUE_TEMPLATE/doc-issue.md index 10e2126f4200..c5781bbbe294 100644 --- a/.github/ISSUE_TEMPLATE/doc-issue.md +++ b/.github/ISSUE_TEMPLATE/doc-issue.md @@ -5,6 +5,8 @@ about: Create an issue to help us improve # Before you open an issue +If the issue is with an ASP.NET Core document, open the issue with the **Content feedback** button at the bottom of that document page. + If the issue is: - A simple typo or similar correction, you can submit a PR. See [the contributor guide](https://docs.microsoft.com/contribute/#quick-edits-to-existing-documents) for instructions. @@ -15,7 +17,7 @@ If the issue is: # Issue description -<include description here> +{ description here } # Software versions diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0c2444ec1610..41e367b9df48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -124,22 +124,20 @@ DocFX requires: ### Mono instructions -* Install Mono via Homebrew: `brew install mono`. -* Download the [latest version of DocFX](https://github.com/dotnet/docfx/releases). -* Extract to `\bin\docfx`. -* Create an alias for **docfx**: +* Install Mono via Homebrew: ``` - function docfx { - mono $HOME/bin/docfx/docfx.exe - } - - function docfx-serve { - mono $HOME/bin/docfx/docfx.exe serve _site - } + brew install mono ``` +* Download the [latest version of DocFX](https://github.com/dotnet/docfx/releases). +* Extract the archive to *$HOME/bin/docfx*. +* Create a pair of aliases for **docfx** in a bash shell. The first alias is used to build the documentation. The second alias is used to build and serve the documentation. -* Run `docfx` in the *Docs\aspnet* or *Docs\aspnetcore* directory to build the site. Run `docfx-serve` to view the site at `http://localhost:8080`. + ``` + alias docfx='mono $HOME/bin/docfx/docfx.exe' + alias docfx-serve='mono $HOME/bin/docfx/docfx.exe --serve' + ``` +* Execute `docfx` from the root of the repo to build the site. Execute `docfx-serve` to view the site at `http://localhost:8080`. ## Voice and tone diff --git a/aspnet/entity-framework.md b/aspnet/entity-framework.md index cd0b83a1b5b4..eece7b470184 100644 --- a/aspnet/entity-framework.md +++ b/aspnet/entity-framework.md @@ -25,4 +25,4 @@ Use Entity Framework with ASP.NET - [Web Forms Tutorials](web-forms/overview/older-versions-getting-started/getting-started-with-ef/the-entity-framework-and-aspnet-getting-started-part-1.md) - [MVC Tutorials](mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md) -- [Sample Application](https://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) +- [Sample Application](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) diff --git a/aspnet/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity.md b/aspnet/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity.md index c3a80f8a3792..7c38a15afc3e 100644 --- a/aspnet/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity.md +++ b/aspnet/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity.md @@ -4,29 +4,26 @@ title: "Account Confirmation and Password Recovery with ASP.NET Identity (C#) | author: HaoK description: "Before doing this tutorial you should first complete Create a secure ASP.NET MVC 5 web app with log in, email confirmation and password reset. This tutorial..." ms.author: riande -ms.date: 03/26/2015 +ms.date: 01/23/2019 ms.assetid: 8d54180d-f826-4df7-b503-7debf5ed9fb3 msc.legacyurl: /identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity msc.type: authoredcontent --- -Account Confirmation and Password Recovery with ASP.NET Identity (C#) -==================== -by [Hao Kung](https://github.com/HaoK), [Pranav Rastogi](https://github.com/rustd), [Rick Anderson]((https://twitter.com/RickAndMSFT)), [Suhas Joshi](https://github.com/suhasj) +# Account confirmation and password recovery with ASP.NET Identity (C#) -> Before doing this tutorial you should first complete [Create a secure ASP.NET MVC 5 web app with log in, email confirmation and password reset](../../../mvc/overview/security/create-an-aspnet-mvc-5-web-app-with-email-confirmation-and-password-reset.md). This tutorial contains more details and will show you how to set up email for local account confirmation and allow users to reset their forgotten password in ASP.NET Identity. This article was written by Rick Anderson ([@RickAndMSFT](https://twitter.com/#!/RickAndMSFT)), Pranav Rastogi ([@rustd](https://twitter.com/rustd)), Hao Kung, and Suhas Joshi. The NuGet sample was written primarily by Hao Kung. +> Before doing this tutorial you should first complete [Create a secure ASP.NET MVC 5 web app with log in, email confirmation and password reset](../../../mvc/overview/security/create-an-aspnet-mvc-5-web-app-with-email-confirmation-and-password-reset.md). This tutorial contains more details and will show you how to set up email for local account confirmation and allow users to reset their forgotten password in ASP.NET Identity. - -A local user account requires the user to create a password for the account, and that password is stored (securely) in the web app. ASP.NET Identity also supports social accounts, which don't require the user to create a password for the app. [Social accounts](../../../mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on.md) use a third party (such as Google, Twitter, Facebook or Microsoft) to authenticate users. This topic covers the following: +A local user account requires the user to create a password for the account, and that password is stored (securely) in the web app. ASP.NET Identity also supports social accounts, which don't require the user to create a password for the app. [Social accounts](../../../mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on.md) use a third party (such as Google, Twitter, Facebook, or Microsoft) to authenticate users. This topic covers the following: - [Create an ASP.NET MVC app](#createMvc) and explore ASP.NET Identity features. -- [Building the Identity sample](#build) +- [Build the Identity sample](#build) - [Set up email confirmation](#email) New users register their email alias, which creates a local account. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image1.png) -Clicking the Register button sends a confirmation email containing a validation token to their email address. +Selecting the Register button sends a confirmation email containing a validation token to their email address. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image2.png) @@ -34,7 +31,7 @@ The user is sent an email with a confirmation token for their account. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image3.png) -Clicking the link confirms the account. +Selecting the link confirms the account. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image4.png) @@ -49,33 +46,30 @@ Local users who forget their password can have a security token sent to their em The user will soon get an email with a link allowing them to reset their password. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image6.png) -Clicking the link will take them to the Reset page. +Selecting the link will take them to the Reset page. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image7.png) -Clicking the **Reset** button will confirm the password has been reset. +Selecting the **Reset** button will confirm the password has been reset. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image8.png) -## Create an ASP.NET Web app - -Start by installing and running [Visual Studio Express 2013 for Web](https://go.microsoft.com/fwlink/?LinkId=299058) or [Visual Studio 2013](https://go.microsoft.com/fwlink/?LinkId=306566). Install Visual Studio [2013 Update 2](https://go.microsoft.com/fwlink/?LinkId=390521) or higher. +## Create an ASP.NET web app -> [!NOTE] -> Warning: You must install Visual Studio [2013 Update 2](https://go.microsoft.com/fwlink/?LinkId=390521) to complete this tutorial. +Start by installing and running [Visual Studio 2017](https://visualstudio.microsoft.com/). -1. Create a new ASP.NET Web project and select the MVC template. Web Forms also supports ASP.NET Identity, so you could follow similar steps in a web forms app. -2. Leave the default authentication as **Individual User Accounts**. -3. Run the app, click the **Register** link and register a user. At this point, the only validation on the email is with the [[EmailAddress]](https://msdn.microsoft.com/library/system.componentmodel.dataannotations.emailaddressattribute(v=vs.110).aspx) attribute. -4. In Server Explorer, navigate to **Data Connections\DefaultConnection\Tables\AspNetUsers**, right click and select **Open table definition**. +1. Create a new ASP.NET Web project and select the MVC template. Web Forms also support ASP.NET Identity, so you could follow similar steps in a web forms app. +2. Change the authentication to **Individual User Accounts**. +3. Run the app, select the **Register** link and register a user. At this point, the only validation on the email is with the [[EmailAddress]](https://msdn.microsoft.com/library/system.componentmodel.dataannotations.emailaddressattribute(v=vs.110).aspx) attribute. +4. In Server Explorer, navigate to **Data Connections\DefaultConnection\Tables\AspNetUsers**, right-click and select **Open table definition**. The following image shows the `AspNetUsers` schema: ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image9.png) -5. Right click on the **AspNetUsers** table and select **Show Table Data**. +5. Right-click on the **AspNetUsers** table and select **Show Table Data**. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image10.png) @@ -91,7 +85,7 @@ The cookie middleware checks the cookie on each request. The `SecurityStampValid Per the comments in the code, the `UseCookieAuthentication` method supports cookie authentication. The `SecurityStamp` field and associated code provides an extra layer of security to your app, when you change your password, you will be logged out of the browser you logged in with. The `SecurityStampValidator.OnValidateIdentity` method enables the app to validate the security token when the user logs in, which is used when you change a password or use the external login. This is needed to ensure that any tokens (cookies) generated with the old password are invalidated. In the sample project, if you change the users password then a new token is generated for the user, any previous tokens are invalidated and the `SecurityStamp` field is updated. -The Identity system allow you to configure your app so when the users security profile changes (for example, when the user changes their password or changes associated login (such as from Facebook, Google, Microsoft account, etc.), the user is logged out of all browser instances. For example, the image below shows the [Single signout sample](https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/SingleSignOutSample/readme.txt) app, which allows the user to sign out of all browser instances (in this case, IE, Firefox and Chrome) by clicking one button. Alternatively, the sample allows you to only log out of a specific browser instance. +The Identity system allow you to configure your app so when the users security profile changes (for example, when the user changes their password or changes associated login (such as from Facebook, Google, Microsoft account, etc.), the user is logged out of all browser instances. For example, the image below shows the [Single signout sample](https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/SingleSignOutSample/readme.txt) app, which allows the user to sign out of all browser instances (in this case, IE, Firefox and Chrome) by selecting one button. Alternatively, the sample allows you to only log out of a specific browser instance. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image11.png) @@ -132,25 +126,25 @@ The OWIN `AuthenticationManager.SignIn` method passes in the `ClaimsIdentity` an ## Email confirmation -It's a good idea to confirm the email a new user register with to verify they are not impersonating someone else (that is, they haven't registered with someone else's email). Suppose you had a discussion forum, you would want to prevent `"bob@example.com"` from registering as `"joe@contoso.com"`. Without email confirmation, `"joe@contoso.com"` could get unwanted email from your app. Suppose Bob accidently registered as `"bib@example.com"` and hadn't noticed it, he wouldn't be able to use password recover because the app doesn't have his correct email. Email confirmation provides only limited protection from bots and doesn't provide protection from determined spammers, they have many working email aliases they can use to register.In the sample below, the user won't be able to change their password until their account has been confirmed (by them clicking on a confirmation link received on the email account they registered with.) You can apply this work flow to other scenarios, for example sending a link to confirm and reset the password on new accounts created by the administrator, sending the user an email when they have changed their profile and so on. You generally want to prevent new users from posting any data to your web site before they have been confirmed by email, a SMS text message or another mechanism. +It's a good idea to confirm the email a new user register with to verify they are not impersonating someone else (that is, they haven't registered with someone else's email). Suppose you had a discussion forum, you would want to prevent `"bob@example.com"` from registering as `"joe@contoso.com"`. Without email confirmation, `"joe@contoso.com"` could get unwanted email from your app. Suppose Bob accidently registered as `"bib@example.com"` and hadn't noticed it, he wouldn't be able to use password recover because the app doesn't have his correct email. Email confirmation provides only limited protection from bots and doesn't provide protection from determined spammers, they have many working email aliases they can use to register.In the sample below, the user won't be able to change their password until their account has been confirmed (by them selecting a confirmation link received on the email account they registered with.) You can apply this work flow to other scenarios, for example sending a link to confirm and reset the password on new accounts created by the administrator, sending the user an email when they have changed their profile and so on. You generally want to prevent new users from posting any data to your web site before they have been confirmed by email, a SMS text message or another mechanism. -## Building a more complete sample +## Build a more complete sample In this section, you'll use NuGet to download a more complete sample we will work with. 1. Create a new ***empty*** ASP.NET Web project. -2. In the Package Manager Console, enter the following the following commands: +2. In the Package Manager Console, enter the following commands: [!code-console[Main](account-confirmation-and-password-recovery-with-aspnet-identity/samples/sample4.cmd)] In this tutorial, we'll use [SendGrid](http://sendgrid.com/) to send email. The `Identity.Samples` package installs the code we will be working with. 3. Set the [project to use SSL](../../../mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on.md). -4. Test local account creation by running the app, clicking on the **Register** link, and posting the registration form. -5. Click the demo email link, which simulates email confirmation. +4. Test local account creation by running the app, selecting the **Register** link, and posting the registration form. +5. Select the demo email link, which simulates email confirmation. 6. Remove the demo email link confirmation code from the sample (The `ViewBag.Link` code in the account controller. See the `DisplayEmail` and `ForgotPasswordConfirmation` action methods and razor views ). -> [!NOTE] -> Warning: If you change any of the security settings in this sample, productions apps will need to undergo a security audit that explicitly calls the changes made. +> [!WARNING] +> If you change any of the security settings in this sample, productions apps will need to undergo a security audit that explicitly calls the changes made. ## Examine the code in App\_Start\IdentityConfig.cs @@ -170,7 +164,7 @@ When a user registers a local account, the `HTTP Post Register` method is called [!code-csharp[Main](account-confirmation-and-password-recovery-with-aspnet-identity/samples/sample6.cs)] -The code above uses the model data to create a new user account using the email and password entered. If the email alias is in the data store, account creation fails and the form is displayed again. The `GenerateEmailConfirmationTokenAsync` method creates a secure confirmation token and stores it in the ASP.NET Identity data store. The [Url.Action](https://msdn.microsoft.com/library/dd505232(v=vs.118).aspx) method creates a link containing the `UserId` and confirmation token. This link is then emailed to the user, the user can click on the link in their email app to confirm their account. +The code above uses the model data to create a new user account using the email and password entered. If the email alias is in the data store, account creation fails and the form is displayed again. The `GenerateEmailConfirmationTokenAsync` method creates a secure confirmation token and stores it in the ASP.NET Identity data store. The [Url.Action](https://msdn.microsoft.com/library/dd505232(v=vs.118).aspx) method creates a link containing the `UserId` and confirmation token. This link is then emailed to the user, the user can select on the link in their email app to confirm their account. @@ -192,9 +186,9 @@ The following code shows how to send email using the [MailMessage](https://msdn. > Security - Never store sensitive data in your source code. The account and credentials are stored in the appSetting. On Azure, you can securely store these values on the **[Configure](https://blogs.msdn.com/b/webdev/archive/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-long-background-process-in-asp-net.aspx)** tab in the Azure portal. See [Best practices for deploying passwords and other sensitive data to ASP.NET and Azure](best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure.md). -Enter your SendGrid credentials, run the app, register with an email alias can click the confirm link in your email. To see how to do this with your [Outlook.com](http://outlook.com) email account, see John Atten's [C# SMTP Configuration for Outlook.Com SMTP Host](http://typecastexception.com/post/2013/12/20/C-SMTP-Configuration-for-OutlookCom-SMTP-Host.aspx) and his[ASP.NET Identity 2.0: Setting Up Account Validation and Two-Factor Authorization](http://typecastexception.com/post/2014/04/20/ASPNET-Identity-20-Setting-Up-Account-Validation-and-Two-Factor-Authorization.aspx) posts. +Enter your SendGrid credentials, run the app, register with an email alias can select the confirm link in your email. To see how to do this with your [Outlook.com](http://outlook.com) email account, see John Atten's [C# SMTP Configuration for Outlook.Com SMTP Host](http://typecastexception.com/post/2013/12/20/C-SMTP-Configuration-for-OutlookCom-SMTP-Host.aspx) and his[ASP.NET Identity 2.0: Setting Up Account Validation and Two-Factor Authorization](http://typecastexception.com/post/2014/04/20/ASPNET-Identity-20-Setting-Up-Account-Validation-and-Two-Factor-Authorization.aspx) posts. -Once a user clicks the **Register** button a confirmation email containing a validation token is sent to their email address. +Once a user selects the **Register** button a confirmation email containing a validation token is sent to their email address. ![](account-confirmation-and-password-recovery-with-aspnet-identity/_static/image12.png) @@ -210,7 +204,7 @@ The following code shows the `POST ForgotPassword` method. The method fails silently if the user email has not been confirmed. If an error was posted for an invalid email address, malicious users could use that information to find valid userId (email aliases) to attack. -The following code shows the `ConfirmEmail` method in the account controller that is called when the user clicks the confirmation link in the email sent to them: +The following code shows the `ConfirmEmail` method in the account controller that is called when the user selects the confirmation link in the email sent to them: [!code-csharp[Main](account-confirmation-and-password-recovery-with-aspnet-identity/samples/sample10.cs)] @@ -227,7 +221,7 @@ The following code shows the email confirmation method: To make your app more secure, ASP.NET Identity supports Two-Factor authentication (2FA). See [ASP.NET Identity 2.0: Setting Up Account Validation and Two-Factor Authorization](http://typecastexception.com/post/2014/04/20/ASPNET-Identity-20-Setting-Up-Account-Validation-and-Two-Factor-Authorization.aspx) by John Atten. Although you can set account lockout on login password attempt failures, that approach makes your login susceptible to [DOS](http://en.wikipedia.org/wiki/Denial-of-service_attack) lockouts. We recommend you use account lockout only with 2FA. -## Additional Resources +## Additional resources - [Overview of Custom Storage Providers for ASP.NET Identity](../extensibility/overview-of-custom-storage-providers-for-aspnet-identity.md) - [MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on](../../../mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on.md) also shows how to add profile information to the users table. diff --git a/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project.md b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project.md index 143edafce77d..d88beb5c89db 100644 --- a/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project.md +++ b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project.md @@ -4,52 +4,49 @@ title: "Adding ASP.NET Identity to an Empty or Existing Web Forms Project | Micr author: raquelsa description: "This tutorial shows you how to add ASP.NET Identity (the new membership system for ASP.NET) to an ASP.NET application. When you create a new Web Forms or MVC..." ms.author: riande -ms.date: 10/23/2013 +ms.date: 01/22/2019 ms.assetid: 1cbc0ed2-5bd6-4b62-8d34-4c193dcd8b25 msc.legacyurl: /identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project msc.type: authoredcontent --- -Adding ASP.NET Identity to an Empty or Existing Web Forms Project -==================== -by [Raquel Soares De Almeida](https://github.com/raquelsa) +# Adding ASP.NET Identity to an Empty or Existing Web Forms Project + > This tutorial shows you how to add [ASP.NET Identity](introduction-to-aspnet-identity.md) (the new membership system for ASP.NET) to an ASP.NET application. > -> When you create a new Web Forms or MVC project in Visual Studio 2013 RTM with Individual Accounts, Visual Studio will install all the required packages and add all necessary classes for you. This tutorial will illustrate the steps to add ASP.NET Identity support to your existing Web Forms project or a new empty project. I will outline all the NuGet packages you need to install, and classes you need to add. I will go over sample Web Forms for registering new users and logging in while highlighting all main entry point APIs for user management and authentication. This sample will use the ASP.NET Identity default implementation for SQL data storage which is built on Entity Framework. This tutorial, we will use LocalDB for the SQL database. +> When you create a new Web Forms or MVC project in Visual Studio 2017 RTM with Individual Accounts, Visual Studio will install all the required packages and add all necessary classes for you. This tutorial will illustrate the steps to add ASP.NET Identity support to your existing Web Forms project or a new empty project. I will outline all the NuGet packages you need to install, and classes you need to add. I will go over sample Web Forms for registering new users and logging in while highlighting all main entry point APIs for user management and authentication. This sample will use the ASP.NET Identity default implementation for SQL data storage which is built on Entity Framework. This tutorial, we will use LocalDB for the SQL database. > -> This tutorial was written by Raquel Soares De Almeida and Rick Anderson ( [@RickAndMSFT](https://twitter.com/#!/RickAndMSFT) ). - -## Getting Started ASP.NET Identity +## Get started with ASP.NET Identity -1. Start by installing and running [Visual Studio Express 2013 for Web](https://go.microsoft.com/fwlink/?LinkId=299058) or [Visual Studio 2013](https://go.microsoft.com/fwlink/?LinkId=306566). -2. Click **New Project** from the Start page, or you can use the menu and select **File**, and then **New Project**. -3. Select **Visual C# i** n the left pane, then **Web** and then select **ASP.NET Web Application**. Name your project "WebFormsIdentity" and then click **OK**. +1. Start by installing and running [Visual Studio 2017](https://visualstudio.microsoft.com/downloads/). +2. Select **New Project** from the Start page, or you can use the menu and select **File**, and then **New Project**. +3. In the left pane, expand **Visual C#**, then select **Web**, then **ASP.NET Web Application (.Net Framework)**. Name your project "WebFormsIdentity" and select **OK**. - ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image1.png) -4. In the **New ASP.NET Project** dialog, select the **Empty** template. + ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image17.png) +4. In the **New ASP.NET Project** dialog, select the **Empty** template. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image2.png) - Notice the **Change Authentication** button is disabled and no authentication support is provided in this template. The Web Forms, MVC and Web API templates allow you to select the authentication approach. For more information, see [Overview of Authentication](../../../visual-studio/overview/2013/creating-web-projects-in-visual-studio.md#auth) . + Notice the **Change Authentication** button is disabled and no authentication support is provided in this template. The Web Forms, MVC and Web API templates allow you to select the authentication approach. -## Adding Identity Packages to your App +## Add Identity packages to your app -In Solution Explorer, right-click your project and select **Manage NuGet Packages**. In the search text box dialog, type "*Identity.E*". Click install for this package. +In Solution Explorer, right-click your project and select **Manage NuGet Packages**. Search for and install the **Microsoft.AspNet.Identity.EntityFramework** package. -![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image3.png) +![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image15.png) -Note that this package will install the dependency packages: EntityFramework and Microsoft ASP.NET Identity Core. +Note that this package will install the dependency packages: **EntityFramework** and **Microsoft ASP.NET Identity Core**. -## Adding Web Forms to Register Users +## Add a web form to register users -1. In **Solution Explorer**, right-click your project and click **Add**, and then **Web Form**. +1. In **Solution Explorer**, right-click your project and select **Add**, and then **Web Form**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image4.png) -2. In the **Specify Name for Item** dialog box, name the new web form **Register**, and then click **OK** -3. Replace the markup in the generated *Register.aspx* file with the code below. The code changes are highlighted. +2. In the **Specify Name for Item** dialog box, name the new web form **Register**, and then select **OK** +3. Replace the markup in the generated *Register.aspx* file with the code below. The code changes are highlighted. - [!code-aspx[Main](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/samples/sample1.aspx?highlight=9,12-40)] + [!code-html[Main](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/samples/sample1.aspx?highlight=9,12-40)] > [!NOTE] > This is just a simplified version of the *Register.aspx* file that is created when you create a new ASP.NET Web Forms project. The markup above adds form fields and a button to register a new user. @@ -64,7 +61,7 @@ Note that this package will install the dependency packages: EntityFramework and > 3. The *UserStore* class is the default EntityFramework implementation of a user store. This class implements the ASP.NET Identity Core's minimal interfaces: *IUserStore*, *IUserLoginStore*, *IUserClaimStore* and *IUserRoleStore*. > 4. The *UserManager* class exposes user related APIs which will automatically save changes to the *UserStore*. > 5. The *IdentityResult* class represents the result of an identity operation. -5. In **Solution Explorer**, right-click your project and click **Add**, **Add ASP.NET Folder** and then **App\_Data**. +5. In **Solution Explorer**, right-click your project and select **Add**, **Add ASP.NET Folder** and then **App\_Data**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image5.png) 6. Open the *Web.config* file and add a connection string entry for the database we will use to store user information. The database will be created at runtime by EntityFramework for the Identity entities. The connection string is similar to one created for you when you create a new Web Forms project. The highlighted code shows the markup you should add: @@ -74,41 +71,42 @@ Note that this package will install the dependency packages: EntityFramework and > [!NOTE] > For Visual Studio 2015 or higher, replace `(localdb)\v11.0` with `(localdb)\MSSQLLocalDB` in your connection string. -7. Right click file *Register.aspx* in your project and select **Set as Start Page**. Press Ctrl + F5 to build and run the web application. Enter a new user name and password and then click on **Register**. +7. Right click file *Register.aspx* in your project and select **Set as Start Page**. Press Ctrl + F5 to build and run the web application. Enter a new user name and password and then select **Register**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image6.png) > [!NOTE] > ASP.NET Identity has support for validation and in this sample you can verify the default behavior on User and Password validators that come from the Identity Core package. The default validator for User (`UserValidator`) has a property `AllowOnlyAlphanumericUserNames` that has default value set to `true`. The default validator for Password (`MinimumLengthValidator`) ensures that password has at least 6 characters. These validators are properties on `UserManager` that can be overridden if you want to have custom validation, -## Verifying the LocalDb Identity Database and Tables Generated by Entity Framework +## Verify the LocalDb Identity database and tables generated by Entity Framework -1. In the **View** menu, click **Server Explorer**. +1. In the **View** menu, select **Server Explorer**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image7.png) -2. Expand **DefaultConnection (WebFormsIdentity)**, expand **Tables**, right click **AspNetUsers** and click **Show Table Data**. +2. Expand **DefaultConnection (WebFormsIdentity)**, expand **Tables**, right-click **AspNetUsers** and then select **Show Table Data**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image8.png) ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image9.png) -## Configuring the application for OWIN authentication +## Configure the application for OWIN authentication At this point we have only added support for creating users. Now, we are going to demonstrate how we can add authentication to login a user. ASP.NET Identity uses Microsoft OWIN Authentication middleware for forms authentication. The OWIN Cookie Authentication is a cookie and claims based authentication mechanism that can be used by any framework hosted on [OWIN](https://msdn.microsoft.com/magazine/dn451439.aspx) or IIS. With this model, the same authentication packages can be used across multiple frameworks including ASP.NET MVC and Web Forms. For more information on project Katana and how to run middleware in a host agnostic see [Getting Started with the Katana Project](https://msdn.microsoft.com/magazine/dn451439.aspx). -## Installing authentication packages to your application +## Install authentication packages to your application -1. In Solution Explorer, right-click your project and select **Manage NuGet Packages**. In the search text box dialog, type "*Identity.Owin*". Click install for this package. +1. In Solution Explorer, right-click your project and select **Manage NuGet Packages**. Search for and install the ***Microsoft.AspNet.Identity.Owin*** package. - ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image10.png) -2. Search for package ***Microsoft.Owin.Host.SystemWeb*** and install it. + ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image16.png) + +2. Search for and install the ***Microsoft.Owin.Host.SystemWeb*** package. > [!NOTE] - > The **Microsoft.Aspnet.Identity.Owin** package contains a set of OWIN extension classes to manage and configure OWIN authentication middleware to be consumed by ASP.NET Identity Core packages. + > The **Microsoft.Aspnet.Identity.Owin** package contains a set of OWIN extension classes to manage and configure OWIN authentication middleware to be consumed by ASP.NET Identity Core packages. > The **Microsoft.Owin.Host.SystemWeb** package contains an OWIN server that enables OWIN-based applications to run on IIS using the ASP.NET request pipeline. For more information see [OWIN Middleware in the IIS integrated pipeline](../../../aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline.md). -## Adding OWIN Startup and Authentication Configuration Classes +## Add OWIN startup and authentication configuration classes -1. In **Solution Explorer**, right-click your project, click **Add**, and then **Add New Item**. In the search text box dialog, type "*owin*". Name the class "*Startup*" and click **Add**. +1. In **Solution Explorer**, right-click your project, select **Add**, and then **Add New Item**. In the search text box dialog, type "*owin*". Name the class "*Startup*" and select **Add**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image11.png) 2. In the Startup.cs file, add the highlighted code shown below to configure OWIN cookie authentication. @@ -118,9 +116,9 @@ At this point we have only added support for creating users. Now, we are going t > [!NOTE] > This class contains the `OwinStartup` attribute for specifying the OWIN startup class. Every OWIN application has a startup class where you specify components for the application pipeline. See [OWIN Startup Class Detection](../../../aspnet/overview/owin-and-katana/owin-startup-class-detection.md) for more info on this model. -## Adding Web Forms for Registering and Logging in Users +## Add web forms for registering and signing in users -1. Open the *Register.cs* file and add the following code which will log in the user when registration succeeds. The changes are highlighted below. +1. Open the *Register.aspx.cs* file and add the following code which signs in the user when registration succeeds. [!code-csharp[Main](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/samples/sample5.cs)] @@ -128,35 +126,35 @@ At this point we have only added support for creating users. Now, we are going t > > - Since ASP.NET Identity and OWIN Cookie Authentication are claims based system, the framework requires the app developer to generate a [ClaimsIdentity](https://msdn.microsoft.com/library/microsoft.identitymodel.claims.claimsidentity.aspx) for the user. ClaimsIdentity has information about all the claims for the user such as what Roles the user belongs to. You can also add more claims for the user at this stage. > - You can sign in the user by using the AuthenticationManager from OWIN and calling `SignIn` and passing in the ClaimsIdentity as shown above. This code will sign in the user and generate a cookie as well. This call is analogous to [FormAuthentication.SetAuthCookie](https://msdn.microsoft.com/library/system.web.security.formsauthentication.setauthcookie.aspx) used by the [FormsAuthentication](https://msdn.microsoft.com/library/system.web.security.formsauthenticationmodule.aspx) module. -2. In **Solution Explorer**, right-click your project click **Add**, and then **Web Form**. Name the web form **Login**. +2. In **Solution Explorer**, right-click your project, select **Add**, and then **Web Form**. Name the web form **Login**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image12.png) -3. Replace the contents of the *Login.aspx* file with the following code: +3. Replace the contents of the *Login.aspx* file with the following code: [!code-aspx[Main](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/samples/sample6.aspx)] -4. Replace the contents of the *Login.aspx.cs* file with the following: +4. Replace the contents of the *Login.aspx.cs* file with the following: [!code-csharp[Main](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/samples/sample7.cs)] > [!NOTE] > - > - The `Page_Load` now checks for the status of current user and takes action based on its `Context.User.Identity.IsAuthenticated` status. + > - The `Page_Load` now checks for the status of current user and takes action based on its `Context.User.Identity.IsAuthenticated` status. > **Display Logged in User Name** : The Microsoft ASP.NET Identity Framework has added extension methods on [System.Security.Principal.IIdentity](https://msdn.microsoft.com/library/system.security.principal.iidentity.aspx) that allows you to get the `UserName` and `UserId` for the logged in User. These extension methods are defined in the `Microsoft.AspNet.Identity.Core` assembly. These extension methods are the replacement for [HttpContext.User.Identity.Name](https://msdn.microsoft.com/library/system.web.httpcontext.user.aspx) . - > - SignIn method: + > - SignIn method: > `This` method replaces the previous `CreateUser_Click` method in this sample and now signs in the user after successfully creating the user. - > The Microsoft OWIN Framework has added extension methods on `System.Web.HttpContext` that allows you to get a reference to an `IOwinContext`. These extension methods are defined in `Microsoft.Owin.Host.SystemWeb` assembly. The `OwinContext` class exposes an `IAuthenticationManager` property that represents the Authentication middleware functionality available on the current request. - > You can sign in the user by using the `AuthenticationManager` from OWIN and calling `SignIn` and passing in the `ClaimsIdentity` as shown above. - > Because ASP.NET Identity and OWIN Cookie Authentication are claims-based system, the framework requires the app to generate a `ClaimsIdentity` for the user. - > The `ClaimsIdentity` has information about all the claims for the user, such as what roles the user belongs to. You can also add more claims for the user at this stage + > The Microsoft OWIN Framework has added extension methods on `System.Web.HttpContext` that allows you to get a reference to an `IOwinContext`. These extension methods are defined in `Microsoft.Owin.Host.SystemWeb` assembly. The `OwinContext` class exposes an `IAuthenticationManager` property that represents the Authentication middleware functionality available on the current request. + > You can sign in the user by using the `AuthenticationManager` from OWIN and calling `SignIn` and passing in the `ClaimsIdentity` as shown above. + > Because ASP.NET Identity and OWIN Cookie Authentication are claims-based system, the framework requires the app to generate a `ClaimsIdentity` for the user. + > The `ClaimsIdentity` has information about all the claims for the user, such as what roles the user belongs to. You can also add more claims for the user at this stage > This code will sign in the user and generate a cookie as well. This call is analogous to [FormAuthentication.SetAuthCookie](https://msdn.microsoft.com/library/system.web.security.formsauthentication.setauthcookie.aspx) used by the [FormsAuthentication](https://msdn.microsoft.com/library/system.web.security.formsauthenticationmodule.aspx) module. - > - `SignOut` method: + > - `SignOut` method: > Gets a reference to the `AuthenticationManager` from OWIN and calls `SignOut`. This is analogous to [FormsAuthentication.SignOut](https://msdn.microsoft.com/library/system.web.security.formsauthentication.signout.aspx) method used by the [FormsAuthentication](https://msdn.microsoft.com/library/system.web.security.formsauthenticationmodule.aspx) module. -5. Press **Ctrl + F5** to build and run the web application. Enter a new user name and password and then click on **Register**. +5. Press **Ctrl + F5** to build and run the web application. Enter a new user name and password and then select **Register**. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image13.png) Note: At this point, the new user is created and logged in. -6. Click on **Log out** button.You will be redirected to the Log in form. -7. Enter an invalid user name or password and Click on **Log in** button. - The `UserManager.Find` method will return null and the error message: " *Invalid user name or password* " will be displayed. +6. Select the **Log out** button. You are redirected to the Log in form. +7. Enter an invalid user name or password and select the **Log in** button. + The `UserManager.Find` method will return null and the error message: " *Invalid user name or password* " will be displayed. ![](adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image14.png) diff --git a/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image15.png b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image15.png new file mode 100644 index 000000000000..22cd59515a0a Binary files /dev/null and b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image15.png differ diff --git a/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image16.png b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image16.png new file mode 100644 index 000000000000..83e22b9a4bed Binary files /dev/null and b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image16.png differ diff --git a/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image17.png b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image17.png new file mode 100644 index 000000000000..16cb1973d92d Binary files /dev/null and b/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project/_static/image17.png differ diff --git a/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity.md b/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity.md index 65cddb922a78..f088ec926128 100644 --- a/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity.md +++ b/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity.md @@ -4,18 +4,15 @@ title: "Introduction to ASP.NET Identity | Microsoft Docs" author: jongalloway description: "The ASP.NET membership system was introduced with ASP.NET 2.0 back in 2005, and since then there have been many changes in the ways web applications typicall..." ms.author: riande -ms.date: 10/17/2013 +ms.date: 01/22/2019 ms.assetid: 38717fc1-5989-43cf-952d-4007cc1dd923 msc.legacyurl: /identity/overview/getting-started/introduction-to-aspnet-identity msc.type: authoredcontent --- Introduction to ASP.NET Identity ==================== -by [Jon Galloway](https://github.com/jongalloway), [Pranav Rastogi](https://github.com/rustd), [Rick Anderson]((https://twitter.com/RickAndMSFT)), [Tom Dykstra](https://github.com/tdykstra) > The ASP.NET membership system was introduced with ASP.NET 2.0 back in 2005, and since then there have been many changes in the ways web applications typically handle authentication and authorization. ASP.NET Identity is a fresh look at what the membership system should be when you are building modern applications for the web, phone, or tablet. -> -> This article was written by Pranav Rastogi ([@rustd](https://twitter.com/rustd)), Jon Galloway ([@jongalloway](https://twitter.com/jongalloway)), Tom Dykstra, and Rick Anderson ([@RickAndMSFT](https://twitter.com/#!/RickAndMSFT) ). ## Background: Membership in ASP.NET @@ -25,7 +22,7 @@ by [Jon Galloway](https://github.com/jongalloway), [Pranav Rastogi](https://gith [ASP.NET Membership](https://msdn.microsoft.com/library/yh26yfzy(v=VS.100).aspx) was designed to solve site membership requirements that were common in 2005, which involved Forms Authentication, and a SQL Server database for user names, passwords, and profile data. Today there is a much broader array of data storage options for web applications, and most developers want to enable their sites to use social identity providers for authentication and authorization functionality. The limitations of ASP.NET Membership's design make this transition difficult: - The database schema was designed for SQL Server and you can't change it. You can add profile information, but the additional data is packed into a different table, which makes it difficult to access by any means except through the Profile Provider API. -- The provider system enables you to change the backing data store, but the system is designed around assumptions appropriate for a relational database. You can write a provider to store membership information in a non-relational storage mechanism, such as Azure Storage Tables, but then you have to work around the relational design by writing a lot of code and a lot of `System.NotImplementedException` exceptions for methods that don't apply to NoSQL databases. +- The provider system enables you to change the backing data store, but the system is designed around assumptions appropriate for a relational database. You can write a provider to store membership information in a non-relational storage mechanism, such as Azure Storage Tables, but then you have to work around the relational design by writing much code and a lot of `System.NotImplementedException` exceptions for methods that don't apply to NoSQL databases. - Since the log-in/log-out functionality is based on Forms Authentication, the membership system can't use [OWIN](../../../aspnet/overview/owin-and-katana/an-overview-of-project-katana.md). OWIN includes middleware components for authentication, including support for log-ins using external identity providers (like Microsoft Accounts, Facebook, Google, Twitter), and log-ins using organizational accounts from on-premises Active Directory or Azure Active Directory. OWIN also includes support for OAuth 2.0, JWT and CORS. ### ASP.NET Simple Membership @@ -42,13 +39,13 @@ Simple Membership did make it easier to customize user profile information, but [ASP.NET Universal Providers](http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx) were developed to make it possible to persist membership information in Microsoft Azure SQL Database, and they also work with SQL Server Compact. The Universal Providers were built on Entity Framework Code First, which means that the Universal Providers can be used to persist data in any store supported by EF. With the Universal Providers, the database schema was cleaned up quite a lot as well. -The Universal Providers are built on the ASP.NET Membership infrastructure, so they still carry the same limitations as the SqlMembership Provider. That is, they were designed for relational databases and it's hard to customize profile and user information. These providers also still use Forms Authentication for log-in and log-out functionality. +The Universal Providers are built on the ASP.NET Membership infrastructure, so they still carry the same limitations as the SqlMembership Provider. That is, they were designed for relational databases and it's hard to customize profile and user information. These providers also still use Forms Authentication for sign-in and sign-out functionality. ## ASP.NET Identity As the membership story in ASP.NET has evolved over the years, the ASP.NET team has learned a lot from feedback from customers. -The assumption that users will log in by entering a user name and password that they have registered in your own application is no longer valid. The web has become more social. Users are interacting with each other in real time through social channels such as Facebook, Twitter, and other social web sites. Developers want users to be able to log in with their social identities so that they can have a rich experience on their web sites. A modern membership system must enable redirection-based log-ins to authentication providers such as Facebook, Twitter, and others. +The assumption that users will sign in by entering a user name and password that they have registered in your own application is no longer valid. The web has become more social. Users are interacting with each other in real time through social channels such as Facebook, Twitter, and other social web sites. Developers want users to be able to sign in with their social identities so that they can have a rich experience on their web sites. A modern membership system must enable redirection-based log-ins to authentication providers such as Facebook, Twitter, and others. As web development evolved, so did the patterns of web development. Unit testing of application code became a core concern for application developers. In 2008 ASP.NET added a new framework based on the Model-View-Controller (MVC) pattern, in part to help developers build unit testable ASP.NET applications. Developers who wanted to unit test their application logic also wanted to be able to do that with the membership system. @@ -79,21 +76,19 @@ Considering these changes in web application development, ASP.NET Identity was d - **Social Login Providers** - You can easily add social log-ins such as Microsoft Account, Facebook, Twitter, Google, and others to your application, and store the user-specific data in your application. -- **Azure Active Directory** - - You can also add log-in functionality using Azure Active Directory, and store the user-specific data in your application. For more information, see [Organizational Accounts](../../../visual-studio/overview/2013/creating-web-projects-in-visual-studio.md#orgauth) in Creating ASP.NET Web Projects in Visual Studio 2013 - **OWIN Integration** - ASP.NET authentication is now based on OWIN middleware that can be used on any OWIN-based host. ASP.NET Identity does not have any dependency on System.Web. It is a fully compliant OWIN framework and can be used in any OWIN hosted application. - ASP.NET Identity uses OWIN Authentication for log-in/log-out of users in the web site. This means that instead of using FormsAuthentication to generate the cookie, the application uses OWIN CookieAuthentication to do that. - **NuGet package** - - ASP.NET Identity is redistributed as a NuGet package which is installed in the ASP.NET MVC, Web Forms and Web API templates that ship with Visual Studio 2013. You can download this NuGet package from the NuGet gallery. + - ASP.NET Identity is redistributed as a NuGet package which is installed in the ASP.NET MVC, Web Forms and Web API templates that ship with Visual Studio 2017. You can download this NuGet package from the NuGet gallery. - Releasing ASP.NET Identity as a NuGet package makes it easier for the ASP.NET team to iterate on new features and bug fixes, and deliver these to developers in an agile manner. -## Getting started with ASP.NET Identity +## Get started with ASP.NET Identity -ASP.NET Identity is used in the Visual Studio 2013 project templates for ASP.NET MVC, Web Forms, Web API and SPA. In this walkthrough, we'll illustrate how the project templates use ASP.NET Identity to add functionality to register, log in and log out a user. +ASP.NET Identity is used in the Visual Studio 2017 project templates for ASP.NET MVC, Web Forms, Web API and SPA. In this walkthrough, we'll illustrate how the project templates use ASP.NET Identity to add functionality to register, sign in and sign out a user. ASP.NET Identity is implemented using the following procedure. The purpose of this article is to give you a high level overview of ASP.NET Identity; you can follow it step by step or just read the details. For more detailed instructions on creating apps using ASP.NET Identity, including using the new API to add users, roles and profile information, see the Next Steps section at the end of this article. @@ -107,29 +102,25 @@ ASP.NET Identity is implemented using the following procedure. The purpose of th - [`Microsoft.AspNet.Identity.Core`](http://www.nuget.org/packages/Microsoft.AspNet.Identity.Core/) This package has the core interfaces for ASP.NET Identity. This package can be used to write an implementation for ASP.NET Identity that targets different persistence stores such as Azure Table Storage, NoSQL databases etc. - [`Microsoft.AspNet.Identity.OWIN`](http://www.nuget.org/packages/Microsoft.AspNet.Identity.Owin/) - This package contains functionality that is used to plug in OWIN authentication with ASP.NET Identity in ASP.NET applications. This is used when you add log in functionality to your application and call into OWIN Cookie Authentication middleware to generate a cookie. + This package contains functionality that is used to plug in OWIN authentication with ASP.NET Identity in ASP.NET applications. This is used when you add sign in functionality to your application and call into OWIN Cookie Authentication middleware to generate a cookie. 3. Creating a user. - Launch the application and then click on the **Register** link to create a user. The following image shows the Register page which collects the user name and password. + Launch the application and then click on the **Register** link to create a user. The following image shows the Register page that collects the user name and password. ![](introduction-to-aspnet-identity/_static/image2.png) - When the user clicks the **Register** button, the `Register` action of the Account controller creates the user by calling the ASP.NET Identity API, as highlighted below: + When the user selects the **Register** button, the `Register` action of the Account controller creates the user by calling the ASP.NET Identity API, as highlighted below: [!code-csharp[Main](introduction-to-aspnet-identity/samples/sample1.cs?highlight=8-9)] -4. Log in. - If the user was successfully created, she is logged in by the `SignInAsync` method. +4. Sign in. + If the user was successfully created, she is signed in by the `SignInAsync` method. - [!code-csharp[Main](introduction-to-aspnet-identity/samples/sample2.cs?highlight=12)] + [!code-csharp[Main](introduction-to-aspnet-identity/samples/sample6.cs?highlight=12)] - [!code-csharp[Main](introduction-to-aspnet-identity/samples/sample3.cs?highlight=5-6)] - The highlighted code above in the `SignInAsync` method generates a [ClaimsIdentity](https://msdn.microsoft.com/library/system.security.claims.claimsidentity.aspx). Since ASP.NET Identity and OWIN Cookie Authentication are claims-based system, the framework requires the app to generate a ClaimsIdentity for the user. ClaimsIdentity has information about all the claims for the user, such as what roles the user belongs to. You can also add more claims for the user at this stage. - - The highlighted code below in the `SignInAsync` method signs in the user by using the AuthenticationManager from OWIN and calling `SignIn` and passing in the ClaimsIdentity. - - [!code-csharp[Main](introduction-to-aspnet-identity/samples/sample4.cs?highlight=8-11)] + The `SignInManager.SignInAsync` method generates a [ClaimsIdentity](https://msdn.microsoft.com/library/system.security.claims.claimsidentity.aspx). Since ASP.NET Identity and OWIN Cookie Authentication are claims-based system, the framework requires the app to generate a ClaimsIdentity for the user. ClaimsIdentity has information about all the claims for the user, such as what roles the user belongs to. + 5. Log off. - Clicking the **Log off** link calls the LogOff action in the account controller. + Select the **Log off** link to call the LogOff action in the account controller. [!code-csharp[Main](introduction-to-aspnet-identity/samples/sample5.cs?highlight=6)] @@ -137,7 +128,7 @@ ASP.NET Identity is implemented using the following procedure. The purpose of th ## Components of ASP.NET Identity -The diagram below shows the components of the ASP.NET Identity system (click on [this](introduction-to-aspnet-identity/_static/image3.png) or on the diagram to enlarge it). The packages in green make up the ASP.NET Identity system. All the other packages are dependencies which are needed to use the ASP.NET Identity system in ASP.NET applications. +The diagram below shows the components of the ASP.NET Identity system (select on [this](introduction-to-aspnet-identity/_static/image3.png) or on the diagram to enlarge it). The packages in green make up the ASP.NET Identity system. All the other packages are dependencies which are needed to use the ASP.NET Identity system in ASP.NET applications. [![](introduction-to-aspnet-identity/_static/image5.png)](introduction-to-aspnet-identity/_static/image4.png) @@ -158,9 +149,5 @@ We hope to soon provide guidance on migrating your existing apps that use ASP.NE The tutorial uses the ASP.NET Identity API to add profile information to the user database, and how to authenticate with Google and Facebook. - [Create an ASP.NET MVC app with auth and SQL DB and deploy to Azure App Service](https://docs.microsoft.com/aspnet/core/security/authorization/secure-data) This tutorial shows how to use the Identity API to add users and roles. -- [Individual User Accounts](../../../visual-studio/overview/2013/creating-web-projects-in-visual-studio.md#indauth) in Creating ASP.NET Web Projects in Visual Studio 2013 -- [Organizational Accounts](../../../visual-studio/overview/2013/creating-web-projects-in-visual-studio.md#orgauth) in Creating ASP.NET Web Projects in Visual Studio 2013 -- [Customizing profile information in ASP.NET Identity in VS 2013 templates](https://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspx) -- [Get more information from Social providers used in the VS 2013 project templates](https://blogs.msdn.com/b/webdev/archive/2013/10/16/get-more-information-from-social-providers-used-in-the-vs-2013-project-templates.aspx) - [https://github.com/rustd/AspnetIdentitySample](https://github.com/rustd/AspnetIdentitySample) Sample application that shows how to add basic roles and user support and how to do roles and user management. diff --git a/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity/samples/sample6.cs b/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity/samples/sample6.cs new file mode 100644 index 000000000000..97999393900d --- /dev/null +++ b/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity/samples/sample6.cs @@ -0,0 +1,27 @@ + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] +public async Task Register(RegisterViewModel model) +{ + if (ModelState.IsValid) + { + var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; + var result = await UserManager.CreateAsync(user, model.Password); + if (result.Succeeded) + { + await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false); + + // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771 + // Send an email with this link + // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); + // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); + // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here"); + + return RedirectToAction("Index", "Home"); + } + AddErrors(result); + } + + // If we got this far, something failed, redisplay form + return View(model); + } \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application.md b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application.md index 5c796cadbf3f..9e385a422f06 100644 --- a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application.md +++ b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application.md @@ -1,24 +1,33 @@ --- uid: mvc/overview/getting-started/database-first-development/creating-the-web-application -title: "EF Database First with ASP.NET MVC: Creating the Web Application and Data Models | Microsoft Docs" +title: "Tutorial: Create the the Web Application and Data Models for EF Database First with ASP.NET MVC" +description: "This tutorial focuses on creating the web application, and generating the data models based on your database tables." author: Rick-Anderson -description: "Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial seri..." ms.author: riande -ms.date: 10/01/2014 +ms.date: 01/28/2019 +ms.topic: tutorial ms.assetid: bc8f2bd5-ff57-4dcd-8418-a5bd517d8953 msc.legacyurl: /mvc/overview/getting-started/database-first-development/creating-the-web-application msc.type: authoredcontent --- -EF Database First with ASP.NET MVC: Creating the Web Application and Data Models -==================== -by [Tom FitzMacken](https://github.com/tfitzmac) -> Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. -> -> This part of the series focuses on creating the web application, and generating the data models based on your database tables. +# Tutorial: Create the the Web Application and Data Models for EF Database First with ASP.NET MVC + Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. -## Create a new ASP.NET Web Application +This tutorial focuses on creating the web application, and generating the data models based on your database tables. + +In this tutorial, you: + +> [!div class="checklist"] +> * Create an ASP.NET web app +> * Generate the models + +## Prerequisites + +* [Getting started with Entity Framework 6 Database First using MVC 5](setting-up-database.md) + +## Create an ASP.NET web app In either a new solution or the same solution as the database project, create a new project in Visual Studio and select the **ASP.NET Web Application** template. Name the project **ContosoSite**. @@ -28,8 +37,6 @@ Click **OK**. In the New ASP.NET Project window, select the **MVC** template. You can clear the **Host in the cloud** option for now because you will deploy the application to the cloud later. Click **OK** to create the application. -![select mvc template](creating-the-web-application/_static/image2.png) - The project is created with the default files and folders. In this tutorial, you will use Entity Framework 6. You can double-check the version of Entity Framework in your project through the Manage NuGet Packages window. If necessary, update your version of Entity Framework. @@ -42,40 +49,32 @@ You will now create Entity Framework models from the database tables. These mode Right-click the **Models** folder, and select **Add** and **New Item**. -![add new item](creating-the-web-application/_static/image4.png) - In the Add New Item window, select **Data** in the left pane and **ADO.NET Entity Data Model** from the options in the center pane. Name the new model file **ContosoModel**. -![create model](creating-the-web-application/_static/image5.png) - Click **Add**. In the Entity Data Model Wizard, select **EF Designer from database**. -![generate from database](creating-the-web-application/_static/image6.png) - Click **Next**. If you have database connections defined within your development environment, you may see one of these connections pre-selected. However, you want to create a new connection to the database you created in the first part of this tutorial. Click the **New Connection** button. -![connect to database](creating-the-web-application/_static/image7.png) - -In the Connection Properties window, provide the name of the local server where your database was created (in this case **(localdb)\ProjectsV12**). After providing the server name, select the ContosoUniversityData from the available databases. +In the Connection Properties window, provide the name of the local server where your database was created (in this case **(localdb)\Projects13**). After providing the server name, select the ContosoUniversityData from the available databases. ![set connection properties](creating-the-web-application/_static/image8.png) Click **OK**. -The correct connection properties are now displayed. You can use the default name for connection in the Web.Config file +The correct connection properties are now displayed. You can use the default name for connection in the Web.Config file. + +Click **Next**. -![connection settings](creating-the-web-application/_static/image9.png) +Select the latest version of Entity Framework. Click **Next**. Select **Tables** to generate models for all three tables. -![select tables](creating-the-web-application/_static/image10.png) - Click **Finish**. If you receive a security warning, select **OK** to continue running the template. @@ -86,12 +85,18 @@ The models are generated from the database tables, and a diagram is displayed th The Models folder now includes many new files related to the models that were generated from the database. -![show new model files](creating-the-web-application/_static/image12.png) - The **ContosoModel.Context.cs** file contains a class that derives from the **DbContext** class, and provides a property for each model class that corresponds to a database table. The **Course.cs**, **Enrollment.cs**, and **Student.cs** files contain the model classes that represent the databases tables. You will use both the context class and the model classes when working with scaffolding. Before proceeding with this tutorial, build the project. In the next section, you will generate code based on the data models, but that section will not work if the project has not been built. -> [!div class="step-by-step"] -> [Previous](setting-up-database.md) -> [Next](generating-views.md) +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Created an ASP.NET web app +> * Generated the models + +Advance to the next tutorial to learn how to create generate code based on the data models. +> [!div class="nextstepaction"] +> [Generating views](generating-views.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image1.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image1.png index 8dc63f0e6e27..f46be41a26f0 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image1.png and b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image10.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image10.png deleted file mode 100644 index c9537aa98446..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image10.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image11.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image11.png index da6958de7802..eb3c4d553709 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image11.png and b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image11.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image12.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image12.png deleted file mode 100644 index 625454559a7e..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image12.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image2.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image2.png deleted file mode 100644 index 3697af1f7d87..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image2.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image3.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image3.png index 557ade812505..1b42b3321f89 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image3.png and b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image3.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image4.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image4.png deleted file mode 100644 index 782f7afbb402..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image5.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image5.png deleted file mode 100644 index 6f03d15b6926..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image6.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image6.png deleted file mode 100644 index f559bb422ec4..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image6.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image7.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image7.png deleted file mode 100644 index 5887bb266258..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image7.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image8.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image8.png index c13cbe71f6dd..48edda2d8b89 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image8.png and b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image8.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image9.png b/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image9.png deleted file mode 100644 index 2d58147389a8..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/creating-the-web-application/_static/image9.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view.md b/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view.md index f295f8d84cd0..460ab87240ad 100644 --- a/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view.md +++ b/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view.md @@ -1,37 +1,55 @@ --- uid: mvc/overview/getting-started/database-first-development/customizing-a-view -title: "EF Database First with ASP.NET MVC: Customizing a View | Microsoft Docs" +title: "Tutorial: Customize view for EF Database First with ASP.NET MVC app" +description: "This tutorial focuses on changing the automatically-generated views to enhance the presentation." author: Rick-Anderson -description: "Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial seri..." ms.author: riande -ms.date: 10/01/2014 +ms.date: 01/24/2019 +ms.topic: tutorial ms.assetid: 269380ff-d7e1-4035-8ad1-fe1316a25f76 msc.legacyurl: /mvc/overview/getting-started/database-first-development/customizing-a-view msc.type: authoredcontent --- -EF Database First with ASP.NET MVC: Customizing a View -==================== -by [Tom FitzMacken](https://github.com/tfitzmac) -> Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. -> -> This part of the series focuses on changing the automatically-generated views to enhance the presentation. +# Tutorial: Customize view for EF Database First with ASP.NET MVC app +Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. -## Add enrolled courses to student details +This tutorial focuses on changing the automatically-generated views to enhance the presentation. + +In this tutorial, you: + +> [!div class="checklist"] +> * Add courses to the student detail page +> * Confirm that the courses are added to the page + +## Prerequisites + +* [Change the database](changing-the-database.md) + +## Add courses to student detail The generated code provides a good starting point for your application but it does not necessarily provide all of the functionality that you need in your application. You can customize the code to meet the particular requirements of your application. Currently, your application does not display the enrolled courses for the selected student. In this section, you will add the enrolled courses for each student to the **Details** view for the student. -Open **Students/Details.cshtml**, and below the last </dl> tab, but before the closing </div> tag, add the following code. +Open **Views** > **Students** > *Details.cshtml*. Below the last </dl> tag, but before the closing </div> tag, add the following code. [!code-cshtml[Main](customizing-a-view/samples/sample1.cshtml)] This code creates a table that displays a row for each record in the Enrollment table for the selected student. The **Display** method renders HTML for the object (modelItem) that represents the expression. You use the Display method (rather than simply embedding the property value in the code) to make sure the value is formatted correctly based on its type and the template for that type. In this example, each expression returns a single property from the current record in the loop, and the values are primitive types which are rendered as text. -Browse to the Students/Index view again and select **Details** for one of the students. You will see the enrolled courses have been included in the view. +## Confirm courses are added + +Run the solution. Click **List of students** and select **Details** for one of the students. You will see the enrolled courses have been included in the view. ![student with enrollment](customizing-a-view/_static/image1.png) -> [!div class="step-by-step"] -> [Previous](changing-the-database.md) -> [Next](enhancing-data-validation.md) +## Next steps +In this tutorial, you: + +> [!div class="checklist"] +> * Added courses to the student detail page +> * Confirmed that the courses are added to the page + +Advance to the next tutorial to learn how to add data annotations to specify validation requirements and display formatting. +> [!div class="nextstepaction"] +> [Enhance data validation](enhancing-data-validation.md) diff --git a/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view/_static/image1.png b/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view/_static/image1.png index 6f555e1f849d..0902cc0af03c 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view/_static/image1.png and b/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation.md b/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation.md index ee072258723a..56220ecc048e 100644 --- a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation.md +++ b/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation.md @@ -1,22 +1,31 @@ --- uid: mvc/overview/getting-started/database-first-development/enhancing-data-validation -title: "EF Database First with ASP.NET MVC: Enhancing Data Validation | Microsoft Docs" +title: "Tutorial: Enhance data validation for EF Database First with ASP.NET MVC app" +description: "This tutorial focuses on adding data annotations to the data model to specify validation requirements and display formatting." author: Rick-Anderson -description: "Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial seri..." ms.author: riande -ms.date: 12/29/2014 +ms.date: 01/28/2019 +ms.topic: tutorial ms.assetid: 0ed5e67a-34c0-4b57-84a6-802b0fb3cd00 msc.legacyurl: /mvc/overview/getting-started/database-first-development/enhancing-data-validation msc.type: authoredcontent --- -EF Database First with ASP.NET MVC: Enhancing Data Validation -==================== -by [Tom FitzMacken](https://github.com/tfitzmac) -> Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. -> -> This part of the series focuses on adding data annotations to the data model to specify validation requirements and display formatting. It was improved based on feedback from users in the comments section. +# Tutorial: Enhance data validation for EF Database First with ASP.NET MVC app +Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. + +This tutorial focuses on adding data annotations to the data model to specify validation requirements and display formatting. It was improved based on feedback from users in the comments section. + +In this tutorial, you: + +> [!div class="checklist"] +> * Add data annotations +> * Add metadata classes + +## Prerequisites + +* [Customize a view](customizing-a-view.md) ## Add data annotations @@ -24,25 +33,21 @@ As you saw in an earlier topic, some data validation rules are automatically app In this tutorial, you will add data annotations to restrict the length of the values provided for the FirstName, LastName, and MiddleName properties. In the database, these values are limited to 50 characters; however, in your web application that character limit is currently not enforced. If a user provides more than 50 characters for one of those values, the page will crash when attempting to save the value to the database. You will also restrict Grade to values between 0 and 4. -Open the **Student.cs** file in the **Models** folder. Add the following highlighted code to the class. +Select **Models** > **ContosoModel.edmx** > **ContosoModel.tt** and open the *Student.cs* file. Add the following highlighted code to the class. [!code-csharp[Main](enhancing-data-validation/samples/sample1.cs?highlight=5,15,17,20)] -In Enrollment.cs, add the following highlighted code. +Open *Enrollment.cs* and add the following highlighted code. [!code-csharp[Main](enhancing-data-validation/samples/sample2.cs?highlight=5,10)] Build the solution. -Browse to a page for editing or creating a student. If you attempt to enter more than 50 characters, an error message is displayed. +Click **List of students** and select **Edit**. If you attempt to enter more than 50 characters, an error message is displayed. ![show error message](enhancing-data-validation/_static/image1.png) -Browse to the page for editing enrollments, and attempt to provide a grade above 4. - -![grade range error](enhancing-data-validation/_static/image2.png) - -For a full list of data validation annotations you can apply to properties and classes, see [System.ComponentModel.DataAnnotations](https://msdn.microsoft.com/library/system.componentmodel.dataannotations.aspx). +Go back to the home page. Click **List of enrollments** and select **Edit**. Attempt to provide a grade above 4. You will receive this error: *The field Grade must be between 0 and 4.* ## Add metadata classes @@ -50,11 +55,9 @@ Adding the validation attributes directly to the model class works when you do n To avoid this problem, you can add a metadata class that contains the attributes. When you associate the model class to the metadata class, those attributes are applied to the model. In this approach, the model class can be regenerated without losing all of the attributes that have been applied to the metadata class. -In the **Models** folder, add a class named **Metadata.cs**. - -![add metadata class](enhancing-data-validation/_static/image3.png) +In the **Models** folder, add a class named *Metadata.cs*. -Replace the code in Metadata.cs with the following code. +Replace the code in *Metadata.cs* with the following code. [!code-csharp[Main](enhancing-data-validation/samples/sample3.cs)] @@ -62,7 +65,7 @@ These metadata classes contain all of the validation attributes that you had pre Now, you must associate the model classes with the metadata classes. -In the **Models** folder, add a class named **PartialClasses.cs**. +In the **Models** folder, add a class named *PartialClasses.cs*. Replace the contents of the file with the following code. @@ -70,14 +73,24 @@ Replace the contents of the file with the following code. Notice that each class is marked as a `partial` class, and each matches the name and namespace as the class that is automatically generated. By applying the metadata attribute to the partial class, you ensure that the data validation attributes will be applied to the automatically-generated class. These attributes will not be lost when you regenerate the model classes because the metadata attribute is applied in partial classes that are not regenerated. -To regenerate the automatically-generated classes, open the ContosoModel.edmx file. Once again, right-click on the design surface and select **Update Model from Database**. Even though you have not changed the database, this process will regenerate the classes. In the **Refresh** tab, select **Tables** and **Finish**. +To regenerate the automatically-generated classes, open the *ContosoModel.edmx* file. Once again, right-click on the design surface and select **Update Model from Database**. Even though you have not changed the database, this process will regenerate the classes. In the **Refresh** tab, select **Tables** and **Finish**. + +Save the *ContosoModel.edmx* file to apply the changes. + +Open the *Student.cs* file or the *Enrollment.cs* file, and notice that the data validation attributes you applied earlier are no longer in the file. However, run the application, and notice that the validation rules are still applied when you enter data. + +## Additional resources + +For a full list of data validation annotations you can apply to properties and classes, see [System.ComponentModel.DataAnnotations](https://msdn.microsoft.com/library/system.componentmodel.dataannotations.aspx). -![refresh tables](enhancing-data-validation/_static/image4.png) +## Next steps -Save the ContosoModel.edmx file to apply the changes. +In this tutorial, you: -Open the Student.cs file or the Enrollment.cs file, and notice that the data validation attributes you applied earlier are no longer in the file. However, run the application, and notice that the validation rules are still applied when you enter data. +> [!div class="checklist"] +> * Added data annotations +> * Added metadata classes -> [!div class="step-by-step"] -> [Previous](customizing-a-view.md) -> [Next](publish-to-azure.md) +Advance to the next tutorial to learn how to publish the web app and database to Azure. +> [!div class="nextstepaction"] +> [Publish to Azure](publish-to-azure.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image1.png b/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image1.png index efa91f274e51..18d53946f439 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image1.png and b/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image2.png b/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image2.png deleted file mode 100644 index 82dc32441f56..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image2.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image3.png b/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image3.png deleted file mode 100644 index b2354322e7eb..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image4.png b/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image4.png deleted file mode 100644 index 3f141146120c..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/enhancing-data-validation/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views.md b/aspnet/mvc/overview/getting-started/database-first-development/generating-views.md index f06f586cc254..29cf65b30460 100644 --- a/aspnet/mvc/overview/getting-started/database-first-development/generating-views.md +++ b/aspnet/mvc/overview/getting-started/database-first-development/generating-views.md @@ -1,54 +1,58 @@ --- uid: mvc/overview/getting-started/database-first-development/generating-views -title: "EF Database First with ASP.NET MVC: Generating Views | Microsoft Docs" +title: "Tutorial: Generate views for EF Database First with ASP.NET MVC app" +description: "This tutorial focuses on using ASP.NET Scaffolding to generate the controllers and views." author: Rick-Anderson -description: "Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial seri..." ms.author: riande -ms.date: 12/29/2014 +ms.date: 01/28/2019 +ms.topic: tutorial ms.assetid: 669367cf-8e30-4eb6-821d-10a7d9bb906c msc.legacyurl: /mvc/overview/getting-started/database-first-development/generating-views msc.type: authoredcontent --- -EF Database First with ASP.NET MVC: Generating Views -==================== -by [Tom FitzMacken](https://github.com/tfitzmac) -> Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. -> -> This part of the series focuses on using ASP.NET Scaffolding to generate the controllers and views. +# Tutorial: Generate views for EF Database First with ASP.NET MVC app +Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. + +This tutorial focuses on using ASP.NET Scaffolding to generate the controllers and views. + +In this tutorial, you: + +> [!div class="checklist"] +> * Add scaffold +> * Add links to new views +> * Display student views +> * Display enrollment views + +## Prerequisite + +* [Create the web application and data models](creating-the-web-application.md) ## Add scaffold You are ready to generate code that will provide standard data operations for the model classes. You add the code by adding a scaffold item. There are many options for the type of scaffolding you can add; in this tutorial, the scaffold will include a controller and views that correspond to the Student and Enrollment models you created in the previous section. -To maintain consistency in your project, you will add the new controller to the existing **Controllers** folder. Right-click the **Controllers** folder, and select **Add** – **New Scaffolded Item**. - -![add scaffold](generating-views/_static/image1.png) +To maintain consistency in your project, you will add the new controller to the existing **Controllers** folder. Right-click the **Controllers** folder, and select **Add** > **New Scaffolded Item**. Select the **MVC 5 Controller with views, using Entity Framework** option. This option will generate the controller and views for updating, deleting, creating and displaying the data in your model. ![add mvc controller](generating-views/_static/image2.png) -Select **Student** for the model class, and select the **ContosoUniversityEntities** for the context class. Keep the controller name as **StudentsController**, - -![specify controller](generating-views/_static/image3.png) +Select **Student (ContosoSite.Models)** for the model class and select the **ContosoUniversityDataEntities (ContosoSite.Models)** for the context class. Keep the controller name as **StudentsController**. Click **Add**. If you receive an error, it may be because you did not build the project in the previous section. If so, try building the project, and then add the scaffolded item again. -After the code generation process is complete, you will see a new controller and views in your project. - -![show views](generating-views/_static/image4.png) +After the code generation process is complete, you will see a new controller and views in your project's **Controllers** and **Views** > **Students** folders. -Perform the same steps again, but add a scaffold for the Enrollment class. When finished, you should have an **EnrollmentsController.cs** file, and a folder under **Views** named **Enrollments** with the Create, Delete, Details, Edit and Index views. -![show views](generating-views/_static/image5.png) +Perform the same steps again, but add a scaffold for the **Enrollment** class. When finished, you have an **EnrollmentsController.cs** file, and a folder under **Views** named **Enrollments** with the Create, Delete, Details, Edit and Index views. ## Add links to new views -To make it easier for you to navigate to your new views, you can add a couple of hyperlinks to the Index views for students and enrollments. Open the file at **Views/Home/Index.cshtml**, which is the home page for your site. Add the following code below the jumbotron. +To make it easier for you to navigate to your new views, you can add a couple of hyperlinks to the Index views for students and enrollments. Open the file at **Views** > **Home** > *Index.cshtml*, which is the home page for your site. Add the following code below the jumbotron. [!code-cshtml[Main](generating-views/samples/sample1.cshtml)] @@ -58,48 +62,40 @@ For the ActionLink method, the first parameter is the text to display in the lin You will verify that the code added to your project correctly displays a list of the students, and enables users to edit, create, or delete the student records in the database. -Right-click the **Views/Home/Index.cshtml** file, and select **View in Browser**. On this page, click the link for the list of students. +Right-click the **Views** > **Home** > *Index.cshtml* file, and select **View in Browser**. On the application home page, select **List of students**. ![](generating-views/_static/image6.png) -On this page, notice the list of the students and links to modify this data. - -![list of students](generating-views/_static/image7.png) - -Click the **Create New** link and provide some values for a new student. +On the **Index** page, notice the list of the students and links to modify this data. Select the **Create New** link and provide some values for a new student. Click **Create**, and notice the new student is added to your list. -![create new student](generating-views/_static/image8.png) - -Click **Create**, and notice the new student is added to your list. - -![list with new student](generating-views/_static/image9.png) - -Select the **Edit** link, and change some of the values for a student. - -![edit student](generating-views/_static/image10.png) - -Click **Save**, and notice the student record has been changed. +Back on the **Index** page, select the **Edit** link, and change some of the values for a student. Click **Save**, and notice the student record has been changed. Finally, select the **Delete** link and confirm that you want to delete the record by clicking the **Delete** button. -![delete student](generating-views/_static/image11.png) - Without writing any code, you have added views that perform common operations on the data in the Student table. You may have noticed that the text label for a field is based on the database property (such as **LastName**) which is not necessarily what you want to display on the web page. For example, you may prefer the label to be **Last Name**. You will fix this display issue later in the tutorial. ## Display enrollment views -Your database includes a one-to-many relationship between the Student and Enrollment tables, and a one-to-many relationship between the Course and Enrollment tables. The views for Enrollment correctly handle these relationships. Navigate to the home page for your site and select the **List of enrollments** link and then the **Create New** link. The view displays a form for creating a new enrollment record. In particular, notice that the form contains two drop-down lists that are populated with values from the related tables. - -![create enrollment](generating-views/_static/image12.png) +Your database includes a one-to-many relationship between the Student and Enrollment tables, and a one-to-many relationship between the Course and Enrollment tables. The views for Enrollment correctly handle these relationships. Navigate to the home page for your site and select the **List of enrollments** link and then the **Create New** link. -Furthermore, validation of the provided values is automatically applied based on the data type of the field. Grade requires a number, so an error message is displayed if you try to provide an incompatible value. +The view displays a form for creating a new enrollment record. In particular, notice that the form contains a **CourseID** drop-down list and a **StudentID** drop-down list. Both are populated with values from the related tables. -![validation message](generating-views/_static/image13.png) +Furthermore, validation of the provided values is automatically applied based on the data type of the field. **Grade** requires a number, so an error message is displayed if you try to provide an incompatible value: *The field Grade must be a number.* You have verified that the automatically-generated views enable users to work with the data in the database. In the next tutorial in this series, you will update the database and make the corresponding changes in the web application. -> [!div class="step-by-step"] -> [Previous](creating-the-web-application.md) -> [Next](changing-the-database.md) +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Added scaffold +> * Added links to new views +> * Displayed student views +> * Displayed enrollment views + +Advance to the next tutorial to learn how to change the database. +> [!div class="nextstepaction"] +> [Change the database](changing-the-database.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image1.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image1.png deleted file mode 100644 index 1da0129c3c6d..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image1.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image10.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image10.png deleted file mode 100644 index c7f8fd4db15b..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image10.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image11.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image11.png deleted file mode 100644 index c8a305915f02..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image11.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image12.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image12.png deleted file mode 100644 index e3d87631150d..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image12.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image2.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image2.png index e8679e408f0f..d42039851b06 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image2.png and b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image2.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image3.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image3.png deleted file mode 100644 index c17264fadbcf..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image4.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image4.png deleted file mode 100644 index 6b48b18831cd..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image5.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image5.png deleted file mode 100644 index dcd602afda9e..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image6.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image6.png index 5f8f9df81904..8fdd5345568f 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image6.png and b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image6.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image7.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image7.png deleted file mode 100644 index 703b1208437d..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image7.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image8.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image8.png deleted file mode 100644 index 977a9c13f545..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image8.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image9.png b/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image9.png deleted file mode 100644 index cb6665c62e4b..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/generating-views/_static/image9.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database.md b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database.md index c23fefbecca5..dc8ae2fb0a66 100644 --- a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database.md +++ b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database.md @@ -1,44 +1,44 @@ --- uid: mvc/overview/getting-started/database-first-development/setting-up-database -title: "Getting Started with Entity Framework 6 Database First using MVC 5 | Microsoft Docs" +title: "Tutorial: Get started with EF Database First using MVC 5" +description: "This tutorial shows how to start with an existing database and quickly create a web application that enables users to interact with the data." author: Rick-Anderson -description: "Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial seri..." ms.author: riande -ms.date: 10/01/2014 +ms.date: 01/28/2019 +ms.topic: tutorial ms.assetid: 095abad4-3bfe-4f06-b092-ae6a735b7e49 msc.legacyurl: /mvc/overview/getting-started/database-first-development/setting-up-database msc.type: authoredcontent --- -Getting Started with Entity Framework 6 Database First using MVC 5 -==================== -by [Tom FitzMacken](https://github.com/tfitzmac) -> Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. In the last part of the series, you will deploy the site and database to Azure. -> -> This part of the series focuses on creating a database and populating it with data. -> -> This series was written with contributions from Tom Dykstra and Rick Anderson. It was improved based on feedback from users in the comments section. +# Tutorial: Get started with EF Database First using MVC 5 +Using MVC, Entity Framework, and ASP.NET Scaffolding, you can create a web application that provides an interface to an existing database. This tutorial series shows you how to automatically generate code that enables users to display, edit, create, and delete data that resides in a database table. The generated code corresponds to the columns in the database table. In the last part of the series, you will deploy the site and database to Azure. -## Introduction +This tutorial shows how to start with an existing database and quickly create a web application that enables users to interact with the data. It uses the Entity Framework 6 and MVC 5 to build the web application. The ASP.NET Scaffolding feature enables you to automatically generate code for displaying, updating, creating and deleting data. Using the publishing tools within Visual Studio, you can easily deploy the site and database to Azure. -This topic shows how to start with an existing database and quickly create a web application that enables users to interact with the data. It uses the Entity Framework 6 and MVC 5 to build the web application. The ASP.NET Scaffolding feature enables you to automatically generate code for displaying, updating, creating and deleting data. Using the publishing tools within Visual Studio, you can easily deploy the site and database to Azure. +This part of the series focuses on creating a database and populating it with data. -This topic addresses the situation where you have a database and want to generate code for a web application based on the fields of that database. This approach is called Database First development. If you do not already have an existing database, you can instead use an approach called Code First development which involves defining data classes and generating the database from the class properties. +This series was written with contributions from Tom Dykstra and Rick Anderson. It was improved based on feedback from users in the comments section. -For an introductory example of Code First development, see [Getting Started with ASP.NET MVC 5](../introduction/getting-started.md). For a more advanced example, see [Creating an Entity Framework Data Model for an ASP.NET MVC 4 App](../getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). +In this tutorial, you: -For guidance on selecting which Entity Framework approach to use, see [Entity Framework Development Approaches](https://msdn.microsoft.com/library/ms178359.aspx#dbfmfcf). +> [!div class="checklist"] +> * Set up the database ## Prerequisites -Visual Studio 2013 or Visual Studio Express 2013 for Web +* [Visual Studio 2017](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=button+cta&utm_content=download+vs2017) + +## Introduction + +This tutorial addresses the situation where you have a database and want to generate code for a web application based on the fields of that database. This approach is called Database First development. If you do not already have an existing database, you can instead use an approach called Code First development which involves defining data classes and generating the database from the class properties. ## Set up the database To mimic the environment of having an existing database, you will first create a database with some pre-filled data, and then create your web application that connects to the database. -This tutorial was developed using LocalDB with either Visual Studio 2013 or Visual Studio Express 2013 for Web. You can use an existing database server instead of LocalDB, but depending on your version of Visual Studio and your type of database, all of the data tools in Visual Studio might not be supported. If the tools are not available for your database, you may need to perform some of the database-specific steps within the management suite for your database. +This tutorial was developed using LocalDB. You can use an existing database server instead of LocalDB, but depending on your version of Visual Studio and your type of database, all of the data tools in Visual Studio might not be supported. If the tools are not available for your database, you may need to perform some of the database-specific steps within the management suite for your database. If you have a problem with the database tools in your version of Visual Studio, make sure you have installed the latest version of the database tools. For information about updating or installing the database tools, see [Microsoft SQL Server Data Tools](https://msdn.microsoft.com/data/hh297027). @@ -48,15 +48,7 @@ Launch Visual Studio and create a **SQL Server Database Project**. Name the proj You now have an empty database project. You will deploy this database to Azure later in this tutorial, so you'll need to set Azure SQL Database as the target platform for the project. Setting the target platform does not actually deploy the database; it only means that the database project will verify that the database design is compatible with the target platform. To set the target platform, open the **Properties** for the project and select **Microsoft Azure SQL Database** for the target platform. -![set target platform](setting-up-database/_static/image2.png) - -You can create the tables needed for this tutorial by adding SQL scripts that define the tables. Right-click your project and add a new item. - -![add new item](setting-up-database/_static/image3.png) - -Add a new table named Student. - -![add student table](setting-up-database/_static/image4.png) +You can create the tables needed for this tutorial by adding SQL scripts that define the tables. Right-click your project and add a new item. Select **Tables and Views** > **Table** and name it *Student*. In the table file, replace the T-SQL command with the following code to create the table. @@ -74,9 +66,7 @@ And, repeat one more time to create a table named Enrollment. [!code-sql[Main](setting-up-database/samples/sample3.sql)] -You can populate your database with data through a script that is run after the database is deployed. Add a Post-Deployment Script to the project. You can use the default name. - -![add post-deployment script](setting-up-database/_static/image6.png) +You can populate your database with data through a script that is run after the database is deployed. Add a Post-Deployment Script to the project. Right-click your project and add a new item. Select **User Scripts** > **Post-Deployment Script**. You can use the default name. Add the following T-SQL code to the post-deployment script. This script simply adds data to the database when no matching record is found. It does not overwrite or delete any data you may have entered into the database. @@ -84,23 +74,29 @@ Add the following T-SQL code to the post-deployment script. This script simply a It is important to note that the post-deployment script is run every time you deploy your database project. Therefore, you need to carefully consider your requirements when writing this script. In some cases, you may wish to start over from a known set of data every time the project is deployed. In other cases, you may not want to alter the existing data in any way. Based on your requirements, you can decide whether you need a post-deployment script or what you need to include in the script. For more information about populating your database with a post-deployment script, see [Including Data in a SQL Server Database Project](https://blogs.msdn.com/b/ssdt/archive/2012/02/02/including-data-in-an-sql-server-database-project.aspx). -You now have 4 SQL script files but no actual tables. You are ready to deploy your database project to localdb. In Visual Studio, click the Start button (or F5) to build and deploy your database project. Check the Output tab to verify that the build and deployment succeeded. - -![show output](setting-up-database/_static/image7.png) - -To see that the new database has been created, open **SQL Server Object Explorer** and look for the name of the project in the correct local database server (in this case **(localdb)\ProjectsV12**). +You now have 4 SQL script files but no actual tables. You are ready to deploy your database project to localdb. In Visual Studio, click the Start button (or F5) to build and deploy your database project. Check the **Output** tab to verify that the build and deployment succeeded. -![show new database](setting-up-database/_static/image8.png) +To see that the new database has been created, open **SQL Server Object Explorer** and look for the name of the project in the correct local database server (in this case **(localdb)\ProjectsV13**). To see that the tables are populated with data, right-click a table, and select **View Data**. ![show table data](setting-up-database/_static/image9.png) -An editable view of the table data is displayed. +An editable view of the table data is displayed. For example, if you select **Tables** > **dbo.course** > **View Data**, you see a table with three columns (**Course**, **Title**, and **Credits**) and four rows. + +## Additional resources + +For an introductory example of Code First development, see [Getting Started with ASP.NET MVC 5](../introduction/getting-started.md). For a more advanced example, see [Creating an Entity Framework Data Model for an ASP.NET MVC 4 App](../getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). + +For guidance on selecting which Entity Framework approach to use, see [Entity Framework Development Approaches](https://msdn.microsoft.com/library/ms178359.aspx#dbfmfcf). + +## Next steps -![show table data results](setting-up-database/_static/image10.png) +In this tutorial, you: -Your database is now set up and populated with data. In the next tutorial, you will create a web application for the database. +> [!div class="checklist"] +> * Set up the database -> [!div class="step-by-step"] -> [Next](creating-the-web-application.md) +Advance to the next tutorial to learn how to create the web application and data models. +> [!div class="nextstepaction"] +> [Create the web application and data models](creating-the-web-application.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image1.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image1.png index 4b03d3f59926..2ca24fa6523e 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image1.png and b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image10.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image10.png deleted file mode 100644 index 287a92ad0239..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image10.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image2.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image2.png deleted file mode 100644 index 3405fcfe6284..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image2.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image3.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image3.png deleted file mode 100644 index 37790d3a05c8..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image4.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image4.png deleted file mode 100644 index 39961498d355..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image5.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image5.png index 7e9698da98bf..ea54caa86ef9 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image5.png and b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image5.png differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image6.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image6.png deleted file mode 100644 index 47abddb3132a..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image6.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image7.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image7.png deleted file mode 100644 index 8dd4d0b306bf..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image7.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image8.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image8.png deleted file mode 100644 index 5d0cacdadfbf..000000000000 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image8.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image9.png b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image9.png index 9127b7672cef..d03ac09c263f 100644 Binary files a/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image9.png and b/aspnet/mvc/overview/getting-started/database-first-development/setting-up-database/_static/image9.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application.md index 457dcca06716..71a27d0025a2 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application.md @@ -1,50 +1,46 @@ --- uid: mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application -title: "Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application (12 of 12) | Microsoft Docs" +title: "Tutorial: Learn about advanced EF Scenarios for an MVC 5 Web app" +description: "This tutorial includes introduces several topics that are useful to be aware of when you go beyond the basics of developing ASP.NET web applications that use Entity Framework Code First." author: tdykstra -description: "The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio..." ms.author: riande -ms.date: 12/08/2014 +ms.date: 01/22/2019 +ms.topic: tutorial ms.assetid: f35a9b0c-49ef-4cde-b06d-19d1543feb0b msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application msc.type: authoredcontent --- -Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application (12 of 12) -==================== -by [Tom Dykstra](https://github.com/tdykstra) -[Download Completed Project](http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) +# Tutorial: Learn about advanced EF Scenarios for an MVC 5 Web app -> The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio. For information about the tutorial series, see [the first tutorial in the series](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). +In the previous tutorial you implemented table-per-hierarchy inheritance. This tutorial includes introduces several topics that are useful to be aware of when you go beyond the basics of developing ASP.NET web applications that use Entity Framework Code First. The first few sections have step-by-step instructions that walk you through the code and using Visual Studio to complete tasks The sections that follow introduce several topics with brief introductions followed by links to resources for more information. -In the previous tutorial you implemented table-per-hierarchy inheritance. This tutorial includes introduces several topics that are useful to be aware of when you go beyond the basics of developing ASP.NET web applications that use Entity Framework Code First. Step-by-step instructions walk you through the code and using Visual Studio for the following topics: +For most of these topics, you'll work with pages that you already created. To use raw SQL to do bulk updates you'll create a new page that updates the number of credits of all courses in the database: -- [Performing raw SQL queries](#rawsql) -- [Performing no-tracking queries](#notracking) -- [Examining SQL sent to the database](#sql) +![Update_Course_Credits_initial_page](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image1.png) -The tutorial introduces several topics with brief introductions followed by links to resources for more information: +In this tutorial, you: -- [Repository and unit of work patterns](#repo) -- [Proxy classes](#proxies) -- [Automatic change detection](#changedetection) -- [Automatic validation](#validation) -- [EF tools for Visual Studio](#tools) -- [Entity Framework source code](#source) +> [!div class="checklist"] +> * Perform raw SQL queries +> * Perform no-tracking queries +> * Examine SQL queries sent to database -The tutorial also includes the following sections: +You also learn about: -- [Summary](#summary) -- [Acknowledgments](#acknowledgments) -- [A note about VB](#vb) -- [Common errors, and solutions or workarounds for them](#errors) +> [!div class="checklist"] +> * Creating an abstraction layer +> * Proxy classes +> * Automatic change detection +> * Automatic validation +> * Entity Framework Power Tools +> * Entity Framework source code -For most of these topics, you'll work with pages that you already created. To use raw SQL to do bulk updates you'll create a new page that updates the number of credits of all courses in the database: +## Prerequisite -![Update_Course_Credits_initial_page](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image1.png) +* [Implementing Inheritance](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md) - -## Performing Raw SQL Queries +## Perform raw SQL queries The Entity Framework Code First API includes methods that enable you to pass SQL commands directly to the database. You have the following options: @@ -64,9 +60,7 @@ In *DepartmentController.cs*, in the `Details` method, replace the `db.Departmen [!code-csharp[Main](advanced-entity-framework-scenarios-for-an-mvc-web-application/samples/sample1.cs?highlight=8-14)] -To verify that the new code works correctly, select the **Departments** tab and then **Details** for one of the departments. - -![Department Details](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image2.png) +To verify that the new code works correctly, select the **Departments** tab and then **Details** for one of the departments. Make sure all of the data displays as expected. ### Calling a Query that Returns Other Types of Objects @@ -80,29 +74,21 @@ In *HomeController.cs*, replace the LINQ statement in the `About` method with a [!code-csharp[Main](advanced-entity-framework-scenarios-for-an-mvc-web-application/samples/sample3.cs?highlight=3-18)] -Run the About page. It displays the same data it did before. - -![About_page](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image3.png) +Run the About page. Verify that it displays the same data it did before. ### Calling an Update Query -Suppose Contoso University administrators want to be able to perform bulk changes in the database, such as changing the number of credits for every course. If the university has a large number of courses, it would be inefficient to retrieve them all as entities and change them individually. In this section you'll implement a web page that enables the user to specify a factor by which to change the number of credits for all courses, and you'll make the change by executing a SQL `UPDATE` statement. The web page will look like the following illustration: - -![Update_Course_Credits_initial_page](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image4.png) +Suppose Contoso University administrators want to be able to perform bulk changes in the database, such as changing the number of credits for every course. If the university has a large number of courses, it would be inefficient to retrieve them all as entities and change them individually. In this section you'll implement a web page that enables the user to specify a factor by which to change the number of credits for all courses, and you'll make the change by executing a SQL `UPDATE` statement. In *CourseContoller.cs*, add `UpdateCourseCredits` methods for `HttpGet` and `HttpPost`: [!code-csharp[Main](advanced-entity-framework-scenarios-for-an-mvc-web-application/samples/sample4.cs)] -When the controller processes an `HttpGet` request, nothing is returned in the `ViewBag.RowsAffected` variable, and the view displays an empty text box and a submit button, as shown in the preceding illustration. - -When the **Update** button is clicked, the `HttpPost` method is called, and `multiplier` has the value entered in the text box. The code then executes the SQL that updates courses and returns the number of affected rows to the view in the `ViewBag.RowsAffected` variable. When the view gets a value in that variable, it displays the number of rows updated instead of the text box and submit button, as shown in the following illustration: - -![Update_Course_Credits_rows_affected_page](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image5.png) +When the controller processes an `HttpGet` request, nothing is returned in the `ViewBag.RowsAffected` variable, and the view displays an empty text box and a submit button. -In *CourseController.cs*, right-click one of the `UpdateCourseCredits` methods, and then click **Add View**. +When the **Update** button is clicked, the `HttpPost` method is called, and `multiplier` has the value entered in the text box. The code then executes the SQL that updates courses and returns the number of affected rows to the view in the `ViewBag.RowsAffected` variable. When the view gets a value in that variable, it displays the number of rows updated instead of the text box and submit button. -![Add_View_dialog_box_for_Update_Course_Credits](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image6.png) +In *CourseController.cs*, right-click one of the `UpdateCourseCredits` methods, and then click **Add View**. The **Add View** dialog appears. Leave the defaults and select **Add**. In *Views\Course\UpdateCourseCredits.cshtml*, replace the template code with the following code: @@ -110,20 +96,15 @@ In *Views\Course\UpdateCourseCredits.cshtml*, replace the template code with the Run the `UpdateCourseCredits` method by selecting the **Courses** tab, then adding "/UpdateCourseCredits" to the end of the URL in the browser's address bar (for example: `http://localhost:50205/Course/UpdateCourseCredits`). Enter a number in the text box: -![Update_Course_Credits_initial_page_with_2_entered](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image7.png) +![Update_Course_Credits_initial_page_with_2_entered](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image1.png) -Click **Update**. You see the number of rows affected: - -![Update_Course_Credits_rows_affected_page](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image8.png) +Click **Update**. You see the number of rows affected. Click **Back to List** to see the list of courses with the revised number of credits. -![Courses_Index_page_showing_revised_credits](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image9.png) - For more information about raw SQL queries, see [Raw SQL Queries](https://msdn.microsoft.com/data/jj592907) on MSDN. - -## No-Tracking Queries +## No-tracking queries When a database context retrieves table rows and creates entity objects that represent them, by default it keeps track of whether the entities in memory are in sync with what's in the database. The data in memory acts as a cache and is used when you update an entity. This caching is often unnecessary in a web application because context instances are typically short-lived (a new one is created and disposed for each request) and the context that reads an entity is typically disposed before that entity is used again. @@ -134,8 +115,7 @@ You can disable tracking of entity objects in memory by using the [AsNoTracking] For an example that demonstrates how to use the [AsNoTracking](https://msdn.microsoft.com/library/gg679352(v=vs.103).aspx) method, see [the earlier version of this tutorial](../../older-versions/getting-started-with-ef-5-using-mvc-4/advanced-entity-framework-scenarios-for-an-mvc-web-application.md). This version of the tutorial doesn't set the Modified flag on a model-binder-created entity in the Edit method, so it doesn't need `AsNoTracking`. - -## Examining SQL sent to the database +## Examine SQL sent to database Sometimes it's helpful to be able to see the actual SQL queries that are sent to the database. In an earlier tutorial you saw how to do that in interceptor code; now you'll see some ways to do it without writing interceptor code. To try this out, you'll look at a simple query and then look at what happens to it as you add options such eager loading, filtering, and sorting. @@ -169,9 +149,7 @@ In *Views\Course\Index.cshtml*, immediately before the opening `table` tag, add [!code-cshtml[Main](advanced-entity-framework-scenarios-for-an-mvc-web-application/samples/sample9.cshtml)] -With the breakpoint still set, run the Course Index page. Continue through the first times that the code hits a breakpoint, so that the page is displayed in the browser. Select a department from the drop-down list and click **Filter**: - -![Course_Index_page_with_department_selected](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image11.png) +With the breakpoint still set, run the Course Index page. Continue through the first times that the code hits a breakpoint, so that the page is displayed in the browser. Select a department from the drop-down list and click **Filter**. This time the first breakpoint will be for the departments query for the drop-down list. Skip that and view the `query` variable the next time the code reaches the breakpoint in order to see what the `Course` query now looks like. You'll see something like the following: @@ -181,9 +159,7 @@ You can see that the query is now a `JOIN` query that loads `Department` data al Remove the `var sql = courses.ToString()` line. - - -## Repository and unit of work patterns +## Create an abstraction layer Many developers write code to implement the repository and unit of work patterns as a wrapper around code that works with the Entity Framework. These patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD). However, writing additional code to implement these patterns is not always the best choice for applications that use EF, for several reasons: @@ -198,6 +174,7 @@ For more information about how to implement the repository and unit of work patt - [Testing with your own test doubles](https://msdn.microsoft.com/data/dn314431) + ## Proxy classes When the Entity Framework creates entity instances (for example, when you execute a query), it often creates them as instances of a dynamically generated derived type that acts as a proxy for the entity. For example, see the following two debugger images. In the first image, you see that the `student` variable is the expected `Student` type immediately after you instantiate the entity. In the second image, after EF has been used to read a student entity from the database, you see the proxy class. @@ -216,7 +193,6 @@ Most of the time you don't need to be aware of this use of proxies, but there ar For more information, see [Working with Proxies](https://msdn.microsoft.com/data/JJ592886.aspx) on MSDN. - ## Automatic change detection The Entity Framework determines how an entity has changed (and therefore which updates need to be sent to the database) by comparing the current values of an entity with the original values. The original values are stored when the entity is queried or attached. Some of the methods that cause automatic change detection are the following: @@ -233,50 +209,29 @@ The Entity Framework determines how an entity has changed (and therefore which u If you're tracking a large number of entities and you call one of these methods many times in a loop, you might get significant performance improvements by temporarily turning off automatic change detection using the [AutoDetectChangesEnabled](https://msdn.microsoft.com/library/system.data.entity.infrastructure.dbcontextconfiguration.autodetectchangesenabled.aspx) property. For more information, see [Automatically Detecting Changes](https://msdn.microsoft.com/data/jj556205) on MSDN. - ## Automatic validation When you call the `SaveChanges` method, by default the Entity Framework validates the data in all properties of all changed entities before updating the database. If you've updated a large number of entities and you've already validated the data, this work is unnecessary and you could make the process of saving the changes take less time by temporarily turning off validation. You can do that using the [ValidateOnSaveEnabled](https://msdn.microsoft.com/library/system.data.entity.infrastructure.dbcontextconfiguration.validateonsaveenabled.aspx) property. For more information, see [Validation](https://msdn.microsoft.com/data/gg193959) on MSDN. - ## Entity Framework Power Tools -[Entity Framework Power Tools](https://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d) is a Visual Studio add-in that was used to create the data model diagrams shown in these tutorials. The tools can also do other function such as generate entity classes based on the tables in an existing database so that you can use the database with Code First. After you install the tools, some additional options appear in context menus. For example, when you right-click your context class in **Solution Explorer**, you get an option to generate a diagram. When you're using Code First you can't change the data model in the diagram, but you can move things around to make it easier to understand. - -![EF in context menu](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image14.png) +[Entity Framework Power Tools](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EntityFramework6PowerToolsCommunityEdition) is a Visual Studio add-in that was used to create the data model diagrams shown in these tutorials. The tools can also do other function such as generate entity classes based on the tables in an existing database so that you can use the database with Code First. After you install the tools, some additional options appear in context menus. For example, when you right-click your context class in **Solution Explorer**, you see and **Entity Framework** option. This gives you the ability to generate a diagram. When you're using Code First you can't change the data model in the diagram, but you can move things around to make it easier to understand. ![EF diagram](advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image15.png) - ## Entity Framework source code The source code for Entity Framework 6 is available at [GitHub](https://github.com/aspnet/EntityFramework6). You can file bugs, and you can contribute your own enhancements to the EF source code. Although the source code is open, Entity Framework is fully supported as a Microsoft product. The Microsoft Entity Framework team keeps control over which contributions are accepted and tests all code changes to ensure the quality of each release. - -## Summary - -This completes this series of tutorials on using the Entity Framework in an ASP.NET MVC application. For more information about how to work with data using the Entity Framework, see the [EF documentation page on MSDN](https://msdn.microsoft.com/data/ee712907) and [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). - -For more information about how to deploy your web application after you've built it, see [ASP.NET Web Deployment - Recommended Resources](../../../../whitepapers/aspnet-web-deployment-content-map.md) in the MSDN Library. - -For information about other topics related to MVC, such as authentication and authorization, see the [ASP.NET MVC - Recommended Resources](../recommended-resources-for-mvc.md). - - ## Acknowledgments - Tom Dykstra wrote the original version of this tutorial, co-authored the EF 5 update, and wrote the EF 6 update. Tom is a senior programming writer on the Microsoft Web Platform and Tools Content Team. - [Rick Anderson](https://blogs.msdn.com/b/rickandy/) (twitter [@RickAndMSFT](http://twitter.com/RickAndMSFT)) did most of the work updating the tutorial for EF 5 and MVC 4 and co-authored the EF 6 update. Rick is a senior programming writer for Microsoft focusing on Azure and MVC. - [Rowan Miller](http://www.romiller.com) and other members of the Entity Framework team assisted with code reviews and helped debug many issues with migrations that arose while we were updating the tutorial for EF 5 and EF 6. - -## VB - -When the tutorial was originally produced for EF 4.1, we provided both C# and VB versions of the completed download project. Due to time limitations and other priorities we have not done that for this version. If you build a VB project using these tutorials and would be willing to share that with others, please let us know. - - -## Common errors, and solutions or workarounds for them +## Troubleshoot common errors ### Cannot create/shadow copy @@ -329,5 +284,37 @@ Solution Check the connection string. If you have manually deleted the database, change the name of the database in the construction string. -> [!div class="step-by-step"] -> [Previous](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md) +## Get the code + +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) + +## Additional resources + + For more information about how to work with data using the Entity Framework, see the [EF documentation page on MSDN](https://msdn.microsoft.com/data/ee712907) and [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). + +For more information about how to deploy your web application after you've built it, see [ASP.NET Web Deployment - Recommended Resources](../../../../whitepapers/aspnet-web-deployment-content-map.md) in the MSDN Library. + +For information about other topics related to MVC, such as authentication and authorization, see the [ASP.NET MVC - Recommended Resources](../recommended-resources-for-mvc.md). + +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Performed raw SQL queries +> * Performed no-tracking queries +> * Examined SQL queries sent to the database + +You also learned about: + +> [!div class="checklist"] +> * Creating an abstraction layer +> * Proxy classes +> * Automatic change detection +> * Automatic validation +> * Entity Framework Power Tools +> * Entity Framework source code + +This completes this series of tutorials on using the Entity Framework in an ASP.NET MVC application. If you want to learn about EF Database First, see the DB First tutorial series. +> [!div class="nextstepaction"] +> [Entity Framework Database First](../database-first-development/setting-up-database.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image1.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image1.png index ccb811713b7a..e159afdbc343 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image1.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image10.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image10.png index c3ff05fa40ff..52beda4dd247 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image10.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image10.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image11.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image11.png deleted file mode 100644 index fcb2d7ab4180..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image11.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image12.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image12.png index ee695db927bb..4fcc08d320b7 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image12.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image12.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image13.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image13.png index 38d88bbd71f7..1c9bbee0bbe4 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image13.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image13.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image14.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image14.png deleted file mode 100644 index a4e697e2c071..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image14.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image2.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image2.png deleted file mode 100644 index c15cf12141b2..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image2.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image3.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image3.png deleted file mode 100644 index 46cd41a6544a..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image4.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image4.png deleted file mode 100644 index ccb811713b7a..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image5.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image5.png deleted file mode 100644 index b9aa0af52fb6..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image6.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image6.png deleted file mode 100644 index ff8b3ee1db5c..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image6.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image7.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image7.png deleted file mode 100644 index ccb811713b7a..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image7.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image8.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image8.png deleted file mode 100644 index b9aa0af52fb6..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image8.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image9.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image9.png deleted file mode 100644 index da1b7889f714..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application/_static/image9.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md index 21630675c72a..ceea57a4f341 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -1,28 +1,23 @@ --- uid: mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application -title: "Async and Stored Procedures with the Entity Framework in an ASP.NET MVC Application | Microsoft Docs" +title: "Tutorial: Use async and stored procedures with EF in an ASP.NET MVC App" +description: "In this tutorial you see how to implement the asynchronous programming model and learn how to use stored procedures." author: tdykstra -description: "The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio..." ms.author: riande -ms.date: 11/07/2014 +ms.date: 01/18/2019 +ms.topic: tutorial ms.assetid: 27d110fc-d1b7-4628-a763-26f1e6087549 msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application msc.type: authoredcontent --- -Async and Stored Procedures with the Entity Framework in an ASP.NET MVC Application -==================== -by [Tom Dykstra](https://github.com/tdykstra) - -[Download Completed Project](http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) - -> The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio. For information about the tutorial series, see [the first tutorial in the series](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). +# Tutorial: Use async and stored procedures with EF in an ASP.NET MVC App In earlier tutorials you learned how to read and update data using the synchronous programming model. In this tutorial you see how to implement the asynchronous programming model. Asynchronous code can help an application perform better because it makes better use of server resources. -In this tutorial you'll also see how to use stored procedures for insert, update, and delete operations on an entity. +In this tutorial you also see how to use stored procedures for insert, update, and delete operations on an entity. -Finally, you'll redeploy the application to Azure, along with all of the database changes that you've implemented since the first time you deployed. +Finally, you redeploy the application to Azure, along with all of the database changes that you've implemented since the first time you deployed. The following illustrations show some of the pages that you'll work with. @@ -30,7 +25,19 @@ The following illustrations show some of the pages that you'll work with. ![Create Department](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png) -## Why bother with asynchronous code +In this tutorial, you: + +> [!div class="checklist"] +> * Learn about asynchronous code +> * Create a Department controller +> * Use stored procedures +> * Deploy to Azure + +## Prerequisites + +* [Updating Related Data](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md) + +## Why use asynchronous code A web server has a limited number of threads available, and in high load situations all of the available threads might be in use. When that happens, the server can't process new requests until the threads are freed up. With synchronous code, many threads may be tied up while they aren't actually doing any work because they're waiting for I/O to complete. With asynchronous code, when a process is waiting for I/O to complete, its thread is freed up for the server to use for processing other requests. As a result, asynchronous code enables server resources to be use more efficiently, and the server is enabled to handle more traffic without delays. @@ -38,11 +45,9 @@ In earlier versions of .NET, writing and testing asynchronous code was complex, For more information about asynchronous programming, see [Use .NET 4.5's async support to avoid blocking calls](../../../../aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/web-development-best-practices.md#async). -## Create the Department controller +## Create Department controller -Create a Department controller the same way you did the earlier controllers, except this time select the **Use async controller** actions check box. - -![Department controller scaffold](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png) +Create a Department controller the same way you did the earlier controllers, except this time select the **Use async controller actions** check box. The following highlights show what was added to the synchronous code for the `Index` method to make it asynchronous: @@ -83,8 +88,6 @@ In the Delete and Details views use the following code: Run the application, and click the **Departments** tab. -![Departments page](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png) - Everything works the same as in the other controllers, but in this controller all of the SQL queries are executing asynchronously. Some things to be aware of when you are using asynchronous programming with the Entity Framework: @@ -92,7 +95,7 @@ Some things to be aware of when you are using asynchronous programming with the - The async code is not thread safe. In other words, in other words, don't try to do multiple operations in parallel using the same context instance. - If you want to take advantage of the performance benefits of async code, make sure that any library packages that you're using (such as for paging), also use async if they call any Entity Framework methods that cause queries to be sent to the database. -## Use stored procedures for inserting, updating, and deleting +## Use stored procedures Some developers and DBAs prefer to use stored procedures for database access. In earlier versions of Entity Framework you can retrieve data using a stored procedure by [executing a raw SQL query](advanced-entity-framework-scenarios-for-an-mvc-web-application.md), but you can't instruct EF to use stored procedures for update operations. In EF 6 it's easy to configure Code First to use stored procedures. @@ -114,7 +117,6 @@ Some developers and DBAs prefer to use stored procedures for database access. In 4. Run the application in debug mode, click the **Departments** tab, and then click **Create New**. 5. Enter data for a new department, and then click **Create**. - ![Create Department](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png) 6. In Visual Studio, look at the logs in the **Output** window to see that a stored procedure was used to insert the new Department row. ![Department Insert SP](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png) @@ -137,12 +139,24 @@ This section requires you to have completed the optional **Deploying the app to The first time you run a page that accesses the database, the Entity Framework runs all of the migrations `Up` methods required to bring the database up to date with the current data model. You can now use all of the web pages that you added since the last time you deployed, including the Department pages that you added in this tutorial. -## Summary +## Get the code + +[Download the Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) -In this tutorial you saw how to improve server efficiency by writing code that executes asynchronously, and how to use stored procedures for insert, update, and delete operations. In the next tutorial, you'll see how to prevent data loss when multiple users try to edit the same record at the same time. +## Additional resources Links to other Entity Framework resources can be found in the [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). -> [!div class="step-by-step"] -> [Previous](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md) -> [Next](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md) +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Learned about asynchronous code +> * Created a Department controller +> * Used stored procedures +> * Deployed to Azure + +Advance to the next article to learn how to handle conflicts when multiple users update the same entity at the same time. +> [!div class="nextstepaction"] +> [Handling concurrency](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md) diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png index abeec9bfa654..c381ed7b4a2b 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png index 9998bfa333f7..7e33125986b3 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png deleted file mode 100644 index 3b490e5883f9..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png deleted file mode 100644 index abeec9bfa654..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png deleted file mode 100644 index 9998bfa333f7..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application.md index 677726fbbfca..11361646d3d6 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -4,7 +4,7 @@ title: "Tutorial: Use connection resiliency and command interception with EF in author: tdykstra description: "In this tutorial you'll learn how to use connection resiliency and command interception. They are two important features of Entity Framework 6." ms.author: riande -ms.date: 01/14/2018 +ms.date: 01/22/2019 ms.topic: tutorial ms.assetid: c89d809f-6c65-4425-a3fa-c9f6e8ac89f2 msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application @@ -168,6 +168,10 @@ Next you'll create the classes that the Entity Framework will call into every ti ![Dummy Exception](connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png) 5. Uncomment the *SetExecutionStrategy* line in *SchoolConfiguration.cs*. +## Get the code + +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) + ## Additional resources Links to other Entity Framework resources can be found in [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application.md index 5598dd26287f..49f59496075c 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application.md @@ -4,7 +4,7 @@ title: "Tutorial: Create a more complex data model for an ASP.NET MVC app" author: tdykstra description: "In this tutorial you'll add more entities and relationships and you'll customize the data model by specifying formatting, validation, and database mapping rules." ms.author: riande -ms.date: 01/16/2019 +ms.date: 01/22/2019 ms.topic: tutorial ms.assetid: 46f7f3c9-274f-4649-811d-92222a9b27e2 msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application @@ -393,6 +393,10 @@ Right-click the `CourseInstructor` table and select **Show Table Data** to verif ![Table_data_in_CourseInstructor_table](creating-a-more-complex-data-model-for-an-asp-net-mvc-application/_static/image17.png) +## Get the code + +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) + ## Additional resources Links to other Entity Framework resources can be found in the [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md index 9b976269f5b8..fb4df9cbd06e 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md @@ -4,7 +4,7 @@ title: "Tutorial: Get Started with Entity Framework 6 Code First using MVC 5 | M description: "In this series of tutorials, you learn how to build an ASP.NET MVC 5 application that uses Entity Framework 6 for data access." author: tdykstra ms.author: riande -ms.date: 01/10/2019 +ms.date: 01/22/2019 ms.topic: tutorial ms.assetid: 00bc8b51-32ed-4fd3-9745-be4c2a9c1eaf msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application @@ -281,6 +281,11 @@ The amount of code you had to write in order for Entity Framework to be able to - A property is interpreted as a foreign key property if it's named *<navigation property name><primary key property name>* (for example, `StudentID` for the `Student` navigation property since the `Student` entity's primary key is `ID`). Foreign key properties can also be named the same simply <primary key property name> (for example, `EnrollmentID` since the `Enrollment` entity's primary key is `EnrollmentID`). You've seen that conventions can be overridden. For example, you specified that table names shouldn't be pluralized, and you'll see later how to explicitly mark a property as a foreign key property. + +## Get the code + +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) + ## Additional resources For more about EF 6, see these articles: diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application/samples/sample2.cshtml b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application/samples/sample2.cshtml index 75ce811e331b..e3682235e723 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application/samples/sample2.cshtml +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application/samples/sample2.cshtml @@ -19,7 +19,7 @@

Download it

-

You can download the completed project from the Microsoft Code Gallery.

-

Download »

+

You can download the completed project.

+

Download »

\ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md index 160e48467242..3500cb31597d 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -1,32 +1,38 @@ --- uid: mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application -title: "Handling Concurrency with the Entity Framework 6 in an ASP.NET MVC 5 Application (10 of 12) | Microsoft Docs" +title: "Tutorial: Handle Concurrency with EF in an ASP.NET MVC 5 app" +description: "This tutorial shows how to use optimistic concurrency to handle conflicts when multiple users update the same entity at the same time." author: tdykstra -description: "The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio..." ms.author: riande -ms.date: 12/08/2014 +ms.date: 01/21/2019 +ms.topic: tutorial ms.assetid: be0c098a-1fb2-457e-b815-ddca601afc65 msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application msc.type: authoredcontent --- -Handling Concurrency with the Entity Framework 6 in an ASP.NET MVC 5 Application (10 of 12) -==================== -by [Tom Dykstra](https://github.com/tdykstra) -[Download Completed Project](http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) +# Tutorial: Handle Concurrency with EF in an ASP.NET MVC 5 app -> The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio. For information about the tutorial series, see [the first tutorial in the series](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). +In earlier tutorials you learned how to update data. This tutorial shows how to use optimistic concurrency to handle conflicts when multiple users update the same entity at the same time. You change the web pages that work with the `Department` entity so that they handle concurrency errors. The following illustrations show the Edit and Delete pages, including some messages that are displayed if a concurrency conflict occurs. +![Department_Edit_page_2_after_clicking_Save](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png) + +![Department_Edit_page_2_after_clicking_Save](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image15.png) -In earlier tutorials you learned how to update data. This tutorial shows how to handle conflicts when multiple users update the same entity at the same time. +In this tutorial, you: -You'll change the web pages that work with the `Department` entity so that they handle concurrency errors. The following illustrations show the Index and Delete pages, including some messages that are displayed if a concurrency conflict occurs. +> [!div class="checklist"] +> * Learn about concurrency conflicts +> * Add optimistic concurrency +> * Modify Department controller +> * Test concurrency handling +> * Update the Delete page -![Department_Index_page_before_edits](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png) +## Prerequisites -![Department_Edit_page_2_after_clicking_Save](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png) +* [Async and Stored Procedures](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md) -## Concurrency Conflicts +## Concurrency conflicts A concurrency conflict occurs when one user displays an entity's data in order to edit it, and then another user updates the same entity's data before the first user's change is written to the database. If you don't enable the detection of such conflicts, whoever updates the database last overwrites the other user's changes. In many applications, this risk is acceptable: if there are few users, or few updates, or if isn't really critical if some changes are overwritten, the cost of programming for concurrency might outweigh the benefit. In that case, you don't have to configure the application to handle concurrency conflicts. @@ -40,12 +46,8 @@ Managing locks has disadvantages. It can be complex to program. It requires sign The alternative to pessimistic concurrency is *optimistic concurrency*. Optimistic concurrency means allowing concurrency conflicts to happen, and then reacting appropriately if they do. For example, John runs the Departments Edit page, changes the **Budget** amount for the English department from $350,000.00 to $0.00. -![Changing_English_dept_budget_to_100000](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png) - Before John clicks **Save**, Jane runs the same page and changes the **Start Date** field from 9/1/2007 to 8/8/2013. -![Changing_English_dept_start_date_to_1999](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png) - John clicks **Save** first and sees his change when the browser returns to the Index page, then Jane clicks **Save**. What happens next is determined by how you handle concurrency conflicts. Some of the options include the following: - You can keep track of which property a user has modified and update only the corresponding columns in the database. In the example scenario, no data would be lost, because different properties were updated by the two users. The next time someone browses the English department, they'll see both John's and Jane's changes — a start date of 8/8/2013 and a budget of Zero dollars. @@ -69,7 +71,7 @@ You can resolve conflicts by handling [OptimisticConcurrencyException](https://m In the remainder of this tutorial you'll add a [rowversion](https://msdn.microsoft.com/library/ms182776(v=sql.110).aspx) tracking property to the `Department` entity, create a controller and views, and test to verify that everything works correctly. -## Add an Optimistic Concurrency Property to the Department Entity +## Add optimistic concurrency In *Models\Department.cs*, add a tracking property named `RowVersion`: @@ -85,7 +87,7 @@ By adding a property you changed the database model, so you need to do another m [!code-console[Main](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/samples/sample3.cmd)] -## Modify the Department Controller +## Modify Department controller In *Controllers\DepartmentController.cs*, add a `using` statement: @@ -129,37 +131,23 @@ In *Views\Department\Edit.cshtml*, add a hidden field to save the `RowVersion` p [!code-cshtml[Main](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/samples/sample12.cshtml?highlight=18)] -## Testing Optimistic Concurrency Handling - -Run the site and click **Departments**: +## Test concurrency handling -![Department_Index_page_before_edits](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png) +Run the site and click **Departments**. Right click the **Edit** hyperlink for the English department and select **Open in new tab,** then click the **Edit** hyperlink for the English department. The two tabs display the same information. -![Department_Edit_page_before_changes](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png) - Change a field in the first browser tab and click **Save**. -![Department_Edit_page_1_after_change](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png) - The browser shows the Index page with the changed value. -![Departments_Index_page_after_first_budget_edit](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png) - -Change a field in the second browser tab and click **Save**. - -![Department_Edit_page_2_after_change](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png) - -Click **Save** in the second browser tab. You see an error message: +Change a field in the second browser tab and click **Save**. You see an error message: ![Department_Edit_page_2_after_clicking_Save](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png) Click **Save** again. The value you entered in the second browser tab is saved along with the original value of the data you changed in the first browser. You see the saved values when the Index page appears. -![Department_Index_page_with_change_from_second_browser](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png) - -## Updating the Delete Page +## Update the Delete page For the Delete page, the Entity Framework detects concurrency conflicts caused by someone else editing the department in a similar manner. When the `HttpGet` `Delete` method displays the confirmation view, the view includes the original `RowVersion` value in a hidden field. That value is then available to the `HttpPost` `Delete` method that's called when the user confirms the deletion. When the Entity Framework creates the SQL `DELETE` command, it includes a `WHERE` clause with the original `RowVersion` value. If the command results in zero rows affected (meaning the row was changed after the Delete confirmation page was displayed), a concurrency exception is thrown, and the `HttpGet Delete` method is called with an error flag set to `true` in order to redisplay the confirmation page with an error message. It's also possible that zero rows were affected because the row was deleted by another user, so in that case a different error message is displayed. @@ -203,30 +191,39 @@ Finally, it adds hidden fields for the `DepartmentID` and `RowVersion` propertie Run the Departments Index page. Right click the **Delete** hyperlink for the English department and select **Open in new tab,** then in the first tab click the **Edit** hyperlink for the English department. -In the first window, change one of the values, and click **Save** : - -![Department_Edit_page_after_change_before_delete](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png) +In the first window, change one of the values, and click **Save**. The Index page confirms the change. -![Departments_Index_page_after_budget_edit_before_delete](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image13.png) - In the second tab, click **Delete**. -![Department_Delete_confirmation_page_before_concurrency_error](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image14.png) - You see the concurrency error message, and the Department values are refreshed with what's currently in the database. ![Department_Delete_confirmation_page_with_concurrency_error](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image15.png) If you click **Delete** again, you're redirected to the Index page, which shows that the department has been deleted. -## Summary +## Get the code + +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) -This completes the introduction to handling concurrency conflicts. For information about other ways to handle various concurrency scenarios, see [Optimistic Concurrency Patterns](https://msdn.microsoft.com/data/jj592904) and [Working with Property Values](https://msdn.microsoft.com/data/jj592677) on MSDN. The next tutorial shows how to implement table-per-hierarchy inheritance for the `Instructor` and `Student` entities. +## Additional resources Links to other Entity Framework resources can be found in the [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). -> [!div class="step-by-step"] -> [Previous](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md) -> [Next](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md) +For information about other ways to handle various concurrency scenarios, see [Optimistic Concurrency Patterns](https://msdn.microsoft.com/data/jj592904) and [Working with Property Values](https://msdn.microsoft.com/data/jj592677) on MSDN. The next tutorial shows how to implement table-per-hierarchy inheritance for the `Instructor` and `Student` entities. + +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Learned about concurrency conflicts +> * Added optimistic concurrency +> * Modified Department controller +> * Tested concurrency handling +> * Updated the Delete page + +Advance to the next article to learn how to implement inheritance in the data model. +> [!div class="nextstepaction"] +> [Implement inheritance in the data model](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png deleted file mode 100644 index a640462dfc48..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png index c50e01a76353..f554d87fb065 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png deleted file mode 100644 index a4d90d40684c..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png deleted file mode 100644 index 084fe6dca73b..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image13.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image13.png deleted file mode 100644 index d5d24be4d8f7..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image13.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image14.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image14.png deleted file mode 100644 index 38e47d1930ca..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image14.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image15.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image15.png index 4686e6da41b7..2aba5de93e76 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image15.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image15.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png deleted file mode 100644 index c50e01a76353..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png deleted file mode 100644 index 45973505491d..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png deleted file mode 100644 index 6bdc3bb673c7..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png deleted file mode 100644 index a640462dfc48..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png deleted file mode 100644 index d0b638d4571a..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png deleted file mode 100644 index 778537ea4e06..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png deleted file mode 100644 index 45973505491d..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png deleted file mode 100644 index 6bdc3bb673c7..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application.md index cd3deda63a03..c1786ad414e4 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application.md @@ -4,7 +4,7 @@ title: "Tutorial: Implement CRUD Functionality with the Entity Framework in ASP. description: "Review and customize the create, read, update, delete (CRUD) code that the MVC scaffolding automatically creates in controllers and views." author: tdykstra ms.author: riande -ms.date: 01/11/2019 +ms.date: 01/22/2019 ms.topic: tutorial ms.assetid: a2f70ba4-83d1-4002-9255-24732726c4f2 msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application @@ -130,7 +130,7 @@ In the following code, `courseID` doesn't match a parameter in the default route [!code-cshtml[Main](implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application/samples/sample9.cshtml)] - *Create.chstml* also includes `@Html.AntiForgeryToken()`, which works with the `ValidateAntiForgeryToken` attribute in the controller to help prevent [cross-site request forgery](../../security/xsrfcsrf-prevention-in-aspnet-mvc-and-web-pages.md) attacks. + *Create.cshtml* also includes `@Html.AntiForgeryToken()`, which works with the `ValidateAntiForgeryToken` attribute in the controller to help prevent [cross-site request forgery](../../security/xsrfcsrf-prevention-in-aspnet-mvc-and-web-pages.md) attacks. No changes are required in *Create.cshtml*. @@ -241,6 +241,10 @@ The base `Controller` class already implements the `IDisposable` interface, so t By default the Entity Framework implicitly implements transactions. In scenarios where you make changes to multiple rows or tables and then call `SaveChanges`, the Entity Framework automatically makes sure that either all of your changes succeed or all fail. If some changes are done first and then an error happens, those changes are automatically rolled back. For scenarios where you need more control—for example, if you want to include operations done outside of Entity Framework in a transaction—see [Working with Transactions](/ef/ef6/saving/transactions). +## Get the code + +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) + ## Additional resources You now have a complete set of pages that perform simple CRUD operations for `Student` entities. You used MVC helpers to generate UI elements for data fields. For more info about MVC helpers, see [Rendering a Form Using HTML Helpers](/previous-versions/aspnet/dd410596(v=vs.98)) (the article is for MVC 3 but is still relevant for MVC 5). @@ -261,4 +265,4 @@ In this tutorial, you: Advance to the next article to learn how to add sorting, filtering, and paging to the project. > [!div class="nextstepaction"] -> [Sorting, Filtering, and Paging](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.md) \ No newline at end of file +> [Sorting, Filtering, and Paging](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.md) diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md index ff5dad264f6e..1d2247ae5464 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -1,28 +1,38 @@ --- uid: mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application -title: "Implementing Inheritance with the Entity Framework 6 in an ASP.NET MVC 5 Application (11 of 12) | Microsoft Docs" +title: "Template: Implement Inheritance with EF in an ASP.NET MVC 5 appS" +description: "This tutorial will show you how to implement inheritance in the data model." author: tdykstra -description: "The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio..." ms.author: riande -ms.date: 11/07/2014 +ms.date: 01/21/2019 +ms.topic: tutorial ms.assetid: 08834147-77ec-454a-bb7a-d931d2a40dab msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application msc.type: authoredcontent --- -Implementing Inheritance with the Entity Framework 6 in an ASP.NET MVC 5 Application (11 of 12) -==================== -by [Tom Dykstra](https://github.com/tdykstra) - -[Download Completed Project](http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) - -> The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio. For information about the tutorial series, see [the first tutorial in the series](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). +# Template: Implement Inheritance with EF in an ASP.NET MVC 5 app In the previous tutorial you handled concurrency exceptions. This tutorial will show you how to implement inheritance in the data model. In object-oriented programming, you can use [inheritance](http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)) to facilitate [code reuse](http://en.wikipedia.org/wiki/Code_reuse). In this tutorial, you'll change the `Instructor` and `Student` classes so that they derive from a `Person` base class which contains properties such as `LastName` that are common to both instructors and students. You won't add or change any web pages, but you'll change some of the code and those changes will be automatically reflected in the database. -## Options for mapping inheritance to database tables +In this tutorial, you: + +> [!div class="checklist"] +> * Learn to map inheritance to database +> * Create the Person class +> * Update Instructor and Student +> * Add Person to the Model +> * Create and Update Migrations +> * Test the implementation +> * Deploy to Azure + +## Prerequisites + +* [Implementing Inheritance](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md) + +## Map inheritance to database The `Instructor` and `Student` classes in the `School` data model have several properties that are identical: @@ -56,7 +66,9 @@ In the *Models* folder, create *Person.cs* and replace the template code with th [!code-csharp[Main](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/samples/sample1.cs)] -## Make Student and Instructor classes inherit from Person +## Update Instructor and Student + +Now update the *Instructor.cs* and *Sudent.cs* to inherit values from the *Person.sc*. In *Instructor.cs*, derive the `Instructor` class from the `Person` class and remove the key and name fields. The code will look like the following example: @@ -66,7 +78,7 @@ Make similar changes to *Student.cs*. The `Student` class will look like the fol [!code-csharp[Main](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/samples/sample3.cs)] -## Add the Person Entity Type to the Model +## Add Person to the Model In *SchoolContext.cs*, add a `DbSet` property for the `Person` entity type: @@ -74,7 +86,7 @@ In *SchoolContext.cs*, add a `DbSet` property for the `Person` entity type: This is all that the Entity Framework needs in order to configure table-per-hierarchy inheritance. As you'll see, when the database is updated, it will have a `Person` table in place of the `Student` and `Instructor` tables. -## Create and Update a Migrations File +## Create and Update Migrations In the Package Manager Console (PMC), enter the following command: @@ -115,19 +127,14 @@ Run the `update-database` command again. > > With a new database, there is no data to migrate, and the `update-database` command is much more likely to complete without errors. For instructions on how to delete the database, see [How to Drop a Database from Visual Studio 2012](http://romiller.com/2013/05/17/how-to-drop-a-database-from-visual-studio-2012/). If you take this approach in order to continue with the tutorial, skip the deployment step at the end of this tutorial or deploy to a new site and database. If you deploy an update to the same site you've been deploying to already, EF will get the same error there when it runs migrations automatically. If you want to troubleshoot a migrations error, the best resource is one of the Entity Framework forums or StackOverflow.com. - -## Testing +## Test the implementation Run the site and try various pages. Everything works the same as it did before. In **Server Explorer,** expand **Data Connections\SchoolContext** and then **Tables**, and you see that the **Student** and **Instructor** tables have been replaced by a **Person** table. Expand the **Person** table and you see that it has all of the columns that used to be in the **Student** and **Instructor** tables. -![Server_Explorer_showing_Person_table](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png) - Right-click the Person table, and then click **Show Table Data** to see the discriminator column. -![](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png) - The following diagram illustrates the structure of the new School database: ![School_database_diagram](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png) @@ -138,22 +145,37 @@ This section requires you to have completed the optional **Deploying the app to 1. In Visual Studio, right-click the project in **Solution Explorer** and select **Publish** from the context menu. - ![Publish in project context menu](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png) 2. Click **Publish**. - ![publish](implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png) + The Web app opens in your default browser. - The Web app will open in your default browser. 3. Test the application to verify it's working. The first time you run a page that accesses the database, the Entity Framework runs all of the migrations `Up` methods required to bring the database up to date with the current data model. -## Summary +## Get the code -You've implemented table-per-hierarchy inheritance for the `Person`, `Student`, and `Instructor` classes. For more information about this and other inheritance structures, see [TPT Inheritance Pattern](https://msdn.microsoft.com/data/jj618293) and [TPH Inheritance Pattern](https://msdn.microsoft.com/data/jj618292) on MSDN. In the next tutorial you'll see how to handle a variety of relatively advanced Entity Framework scenarios. +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) + +## Additional resources Links to other Entity Framework resources can be found in the [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). -> [!div class="step-by-step"] -> [Previous](handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application.md) -> [Next](advanced-entity-framework-scenarios-for-an-mvc-web-application.md) +For more information about this and other inheritance structures, see [TPT Inheritance Pattern](https://msdn.microsoft.com/data/jj618293) and [TPH Inheritance Pattern](https://msdn.microsoft.com/data/jj618292) on MSDN. In the next tutorial you'll see how to handle a variety of relatively advanced Entity Framework scenarios. + +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Learned to map inheritance to database +> * Created the Person class +> * Updated Instructor and Student +> * Added Person to the Model +> * Created and Update Migrations +> * Tested the implementation +> * Deployed to Azure + +Advance to the next article to learn about topics that are useful to be aware of when you go beyond the basics of developing ASP.NET web applications that use Entity Framework Code First. +> [!div class="nextstepaction"] +> [Advanced Entity Framework Scenarios](advanced-entity-framework-scenarios-for-an-mvc-web-application.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png deleted file mode 100644 index 4393b2467e41..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png deleted file mode 100644 index e8cec48b13e3..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png deleted file mode 100644 index ee53fecedff8..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png deleted file mode 100644 index 776a5c81f091..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application.md index 233019431e18..a38ee790b6a0 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -1,31 +1,35 @@ --- uid: mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application -title: "Code First Migrations and Deployment with the Entity Framework in an ASP.NET MVC Application | Microsoft Docs" +title: "Tutorial: Use EF Migrations in an ASP.NET MVC app and deploy to Azure" author: tdykstra -description: "The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio..." +description: "In this tutorial, you enable Code First migrations and deploy the application to the cloud in Azure." ms.author: riande -ms.date: 10/08/2018 +ms.date: 01/16/2019 +ms.topic: tutorial ms.assetid: d4dfc435-bda6-4621-9762-9ba270f8de4e msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application msc.type: authoredcontent --- -Code First migrations and deployment with the Entity Framework in an ASP.NET MVC application -==================== -by [Tom Dykstra](https://github.com/tdykstra) -[Download Completed Project](http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) +# Tutorial: Use EF Migrations in an ASP.NET MVC app and deploy to Azure -> The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio. For information about the tutorial series, see [the first tutorial in the series](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). - -So far the application has been running locally in IIS Express on your development computer. To make a real application available for other people to use over the Internet, you have to deploy it to a web hosting provider. In this tutorial, you'll deploy the Contoso University application to the cloud in Azure. - -The tutorial contains the following sections: +So far the Contoso University sample web application has been running locally in IIS Express on your development computer. To make a real application available for other people to use over the Internet, you have to deploy it to a web hosting provider. In this tutorial, you enable Code First migrations and deploy the application to the cloud in Azure: - Enable Code First Migrations. The Migrations feature enables you to change the data model and deploy your changes to production by updating the database schema without having to drop and re-create the database. - Deploy to Azure. This step is optional; you can continue with the remaining tutorials without having deployed the project. We recommend that you use a continuous integration process with source control for deployment, but this tutorial does not cover those topics. For more information, see the [source control](xref:aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/source-control) and [continuous integration](xref:aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/continuous-integration-and-continuous-delivery) chapters of [Building Real-World Cloud Apps with Azure](xref:aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/introduction). +In this tutorial, you: + +> [!div class="checklist"] +> * Enable Code First migrations +> * Deploy the app in Azure (optional) + +## Prerequisites + +- [Connection Resiliency and Command Interception](connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application.md) + ## Enable Code First migrations When you develop a new application, your data model changes frequently, and each time the model changes, it gets out of sync with the database. You have configured the Entity Framework to automatically drop and re-create the database each time you change the data model. When you add, remove, or change entity classes or change your `DbContext` class, the next time you run the application it automatically deletes your existing database, creates a new one that matches the model, and seeds it with test data. @@ -49,15 +53,11 @@ This method of keeping the database in sync with the data model works well until add-migration InitialCreate ``` - ![enable-migrations command](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png) - The `enable-migrations` command creates a *Migrations* folder in the ContosoUniversity project, and it puts in that folder a *Configuration.cs* file that you can edit to configure Migrations. (If you missed the step above that directs you to change the database name, Migrations will find the existing database and automatically do the `add-migration` command. That's okay, it just means you won't run a test of the migrations code before you deploy the database. Later when you run the `update-database` command nothing will happen because the database already exists.) - ![Migrations folder](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png) - - Like the initializer class that you saw earlier, the `Configuration` class includes a `Seed` method. + Open the *ContosoUniversity\Migrations\Configuration.cs* file. Like the initializer class that you saw earlier, the `Configuration` class includes a `Seed` method. [!code-csharp[Main](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/samples/sample3.cs)] @@ -115,8 +115,6 @@ If you created the initial migration when the database already exists, the datab `update-database` - ![](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png) - The `update-database` command runs the `Up` method to create the database and then it runs the `Seed` method to populate the database. The same process will run automatically in production after you deploy the application, as you'll see in the following section. 2. Use **Server Explorer** to inspect the database as you did in the first tutorial, and run the application to verify that everything still works the same as before. @@ -151,8 +149,6 @@ You'll deploy the database to Azure SQL database. SQL database is a cloud-based 2. Enter a string in the **App name** box to use as the unique URL for your application. The complete URL will consist of what you enter here plus the default domain of Azure App Services (.azurewebsites.net). If the **App name** is already taken, the Wizard notifies you with a red *The app name is not available* message. If the **App name** is available, you see a green checkmark. - ![Create with Database link in Management Portal](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/create-web-app-sql-resource.png) - 3. In the **Subscription** box, choose the Azure Subscription in which you want the **App Service** to reside. 4. In the **Resource Group** text box, choose a Resource Group or create a new one. This setting specifies which data center your web site will run in. For more information about Resource Groups, see [Resource groups](/azure/azure-resource-manager/resource-group-overview#resource-groups). @@ -161,8 +157,6 @@ You'll deploy the database to Azure SQL database. SQL database is a cloud-based 6. Click **SQL Database**, and then choose **Create a new database** or select an existing database. - ![](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/new-sql-database.png) - 7. In the **Name** box, enter a name for your database. 8. Click the **Target Server** box, and then select **Create a new server**. Alternatively, if you previously created a server, you can select that server from list of available servers. 9. Choose **Pricing tier** section, choose *Free*. If additional resources are needed, the database can be scaled up at any time. To learn more on Azure SQL Pricing, see [Azure SQL Database pricing](https://azure.microsoft.com/pricing/details/sql-database/managed/). @@ -181,8 +175,6 @@ You'll deploy the database to Azure SQL database. SQL database is a cloud-based 1. In Visual Studio, right-click the project in **Solution Explorer** and select **Publish** from the context menu. - ![Publish menu item in Solution Explorer](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png) - 2. On the **Pick a publish target** page, choose **App Service** and then **Select Existing**, and then choose **Publish**. ![Pick a publish target page](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-select-existing-azure-app-service.png) @@ -191,12 +183,8 @@ You'll deploy the database to Azure SQL database. SQL database is a cloud-based 4. On the **App Service** page, select the **Subscription** you added the App Service to. Under **View**, select **Resource Group**. Expand the resource group you added the App Service to, and then select the App Service. Choose **OK** to publish the app. - ![Select App Service](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/app-service-page.png) - 5. The **Output** window shows what deployment actions were taken and reports successful completion of the deployment. - ![Output window reporting successful deployment](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-output.png) - 6. Upon successful deployment, the default browser automatically opens to the URL of the deployed web site. ![Students_index_page_with_paging](migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/cloud-app-browser.png) @@ -230,14 +218,22 @@ In the deployment section, you saw the [MigrateDatabaseToLatestVersion](https:// For more information about initializers, see [Understanding Database Initializers in Entity Framework Code First](http://www.codeguru.com/csharp/article.php/c19999/Understanding-Database-Initializers-in-Entity-Framework-Code-First.htm) and chapter 6 of the book [Programming Entity Framework: Code First](http://shop.oreilly.com/product/0636920022220.do) by Julie Lerman and Rowan Miller. -## Summary +## Get the code -In this tutorial, you learned how to enable migrations and deploy the application. In the next tutorial, you'll begin looking at more advanced topics by expanding the data model. +[Download the Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) -Please leave feedback on how you liked this tutorial and what we could improve. +## Additional resources Links to other Entity Framework resources can be found in [ASP.NET Data Access - Recommended Resources](xref:whitepapers/aspnet-data-access-content-map). -> [!div class="step-by-step"] -> [Previous](xref:mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application) -> [Next](xref:mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application) +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Enabled Code First migrations +> * Deployed the app in Azure (optional) + +Advance to the next article to learn how to create a more complex data model for an ASP.NET MVC Application. +> [!div class="nextstepaction"] +> [Create a more complex data model](creating-a-more-complex-data-model-for-an-asp-net-mvc-application.md) diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/app-service-page.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/app-service-page.png deleted file mode 100644 index a130744287c2..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/app-service-page.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/cloud-app-browser.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/cloud-app-browser.png index b148f91b6278..4fd708aec76a 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/cloud-app-browser.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/cloud-app-browser.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/create-web-app-sql-resource.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/create-web-app-sql-resource.png deleted file mode 100644 index 68c29a115c14..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/create-web-app-sql-resource.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png deleted file mode 100644 index be415610218b..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png deleted file mode 100644 index ee53fecedff8..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png deleted file mode 100644 index d46db01f4db6..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png deleted file mode 100644 index 01d24ac39a86..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/new-sql-database.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/new-sql-database.png deleted file mode 100644 index 89581d14f493..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/new-sql-database.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-output.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-output.png deleted file mode 100644 index 59a0364070d2..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-output.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-select-existing-azure-app-service.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-select-existing-azure-app-service.png index d9daf48dae6b..e38011964a8f 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-select-existing-azure-app-service.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application/_static/publish-select-existing-azure-app-service.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md index 0c06ac75b947..70a8347c32ab 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -4,7 +4,7 @@ title: "Tutorial: Read related data with EF in an ASP.NET MVC app" description: "In this tutorial you'll read and display related data — that is, data that the Entity Framework loads into navigation properties." author: tdykstra ms.author: riande -ms.date: 01/17/2019 +ms.date: 01/22/2019 ms.topic: tutorial ms.assetid: 18cdd896-8ed9-4547-b143-114711e3eafb msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application @@ -239,6 +239,10 @@ Notice that you use the `Collection` method to load a collection property, but f Run the Instructor Index page now and you'll see no difference in what's displayed on the page, although you've changed how the data is retrieved. +## Get the code + +[Download Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) + ## Additional resources Links to other Entity Framework resources can be found in the [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.md index 01d7008fc8ce..6e05d163da3e 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -1,29 +1,37 @@ --- uid: mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application -title: "Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application | Microsoft Docs" +title: "Tutorial: Add sorting, filtering, and paging with the Entity Framework in an ASP.NET MVC application | Microsoft Docs" author: tdykstra -description: "The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio..." +description: "In this tutorial you add sorting, filtering, and paging functionality to the **Students** Index page. You also create a simple grouping page." ms.author: riande -ms.date: 10/08/2018 +ms.date: 01/14/2019 ms.assetid: d5723e46-41fe-4d09-850a-e03b9e285bfa msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application msc.type: authoredcontent +ms.topic: tutorial --- -# Sorting, filtering, and paging with the Entity Framework in an ASP.NET MVC application -by [Tom Dykstra](https://github.com/tdykstra) +# Tutorial: Add sorting, filtering, and paging with the Entity Framework in an ASP.NET MVC application -[Download Completed Project](http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) +In the [previous tutorial](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md), you implemented a set of web pages for basic CRUD operations for `Student` entities. In this tutorial you add sorting, filtering, and paging functionality to the **Students** Index page. You also create a simple grouping page. -> The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio. For information about the tutorial series, see [the first tutorial in the series](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). +The following image shows what the page will look like when you're done. The column headings are links that the user can click to sort by that column. Clicking a column heading repeatedly toggles between ascending and descending sort order. -In the previous tutorial, you implemented a set of web pages for basic CRUD operations for `Student` entities. In this tutorial you'll add sorting, filtering, and paging functionality to the **Students** Index page. You'll also create a page that does simple grouping. +![Students_Index_page_with_paging](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png) -The following illustration shows what the page will look like when you're done. The column headings are links that the user can click to sort by that column. Clicking a column heading repeatedly toggles between ascending and descending sort order. +In this tutorial, you: -![Students_Index_page_with_paging](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png) +> [!div class="checklist"] +> * Add column sort links +> * Add a Search box +> * Add paging +> * Create an About page + +## Prerequisites + +* [Implementing Basic CRUD Functionality](implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application.md) -## Add column sort links to the Students index page +## Add column sort links To add sorting to the Student Index page, you'll change the `Index` method of the `Student` controller and add code to the `Student` Index view. @@ -64,13 +72,9 @@ As an alternative to writing different LINQ statements for each sort order, you 2. Run the page and click the **Last Name** and **Enrollment Date** column headings to verify that sorting works. - ![Students_Index_page_with_sort_hyperlinks](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png) - After you click the **Last Name** heading, students are displayed in descending last name order. - ![Student index view in web browser](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png) - -## Add a search box to the Students index page +## Add a Search box To add filtering to the Students index page, you'll add a text box and a submit button to the view and make corresponding changes in the `Index` method. The text box lets you enter a string to search for in the first name and last name fields. @@ -97,15 +101,11 @@ The code adds a `searchString` parameter to the `Index` method. The search strin 2. Run the page, enter a search string, and click **Search** to verify that filtering is working. - ![Students_Index_page_with_search_box](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png) - Notice the URL doesn't contain the "an" search string, which means that if you bookmark this page, you won't get the filtered list when you use the bookmark. This applies also to the column sort links, as they will sort the whole list. You'll change the **Search** button to use query strings for filter criteria later in the tutorial. -## Add paging to the Students index page +## Add paging -To add paging to the Students index page, you'll start by installing the **PagedList.Mvc** NuGet package. Then you'll make additional changes in the `Index` method and add paging links to the `Index` view. **PagedList.Mvc** is one of many good paging and sorting packages for ASP.NET MVC, and its use here is intended only as an example, not as a recommendation for it over other options. The following illustration shows the paging links. - -![Students_index_page_with_paging](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png) +To add paging to the Students index page, you'll start by installing the **PagedList.Mvc** NuGet package. Then you'll make additional changes in the `Index` method and add paging links to the `Index` view. **PagedList.Mvc** is one of many good paging and sorting packages for ASP.NET MVC, and its use here is intended only as an example, not as a recommendation for it over other options. ### Install the PagedList.MVC NuGet package @@ -119,8 +119,6 @@ The NuGet **PagedList.Mvc** package automatically installs the **PagedList** pac Install-Package PagedList.Mvc ``` - ![Install PagedList.Mvc](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png) - 3. Build the project. ### Add paging functionality to the Index method @@ -191,13 +189,9 @@ The NuGet **PagedList.Mvc** package automatically installs the **PagedList** pac 2. Run the page. - ![Students index page with paging](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png) - Click the paging links in different sort orders to make sure paging works. Then enter a search string and try paging again to verify that paging also works correctly with sorting and filtering. - ![Students index page with search filter text](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png) - -## Create an About page that shows Student statistics +## Create an About page For the Contoso University website's About page, you'll display how many students have enrolled for each enrollment date. This requires grouping and simple calculations on the groups. To accomplish this, you'll do the following: @@ -243,14 +237,24 @@ Create a *ViewModels* folder in the project folder. In that folder, add a class ![About_page](sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png) -## Summary +## Get the code -In this tutorial you've seen how to create a data model and implement basic CRUD, sorting, filtering, paging, and grouping functionality. In the next tutorial, you'll begin looking at more advanced topics by expanding the data model. +[Download the Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) -Please leave feedback on how you liked this tutorial and what we could improve. +## Additional resources Links to other Entity Framework resources can be found in [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). -> [!div class="step-by-step"] -> [Previous](implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application.md) -> [Next](connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application.md) +## Next steps + +In this tutorial, you: + +> [!div class="checklist"] +> * Add column sort links +> * Add a Search box +> * Add paging +> * Create an About page + +Advance to the next article to learn how to use connection resiliency and command interception. +> [!div class="nextstepaction"] +> [Connection resiliency and command interception](connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application.md) \ No newline at end of file diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png index d1d9951db5ee..eac4913839b1 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png deleted file mode 100644 index 4c774cd0a0d8..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png deleted file mode 100644 index 6b9142b4b3ce..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png deleted file mode 100644 index b78f720d37d1..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png deleted file mode 100644 index d1d9951db5ee..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png deleted file mode 100644 index 22cd032e6776..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png deleted file mode 100644 index d1d9951db5ee..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png deleted file mode 100644 index 8a031fb2eb4c..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png index c57165ca8ddc..a8e2444dfbcf 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md index e6987628b9f5..b70d52efe76c 100644 --- a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md +++ b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md @@ -1,24 +1,19 @@ --- uid: mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application -title: "Updating Related Data with the Entity Framework in an ASP.NET MVC Application | Microsoft Docs" +title: "Tutorial: Update related data with EF in an ASP.NET MVC app" +description: "In this tutorial you'll update related data. For most relationships, this can be done by updating either foreign key fields or navigation properties." author: tdykstra -description: "The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio..." ms.author: riande -ms.date: 05/01/2015 +ms.date: 01/17/2019 +ms.topic: tutorial ms.assetid: 7ba88418-5d0a-437d-b6dc-7c3816d4ec07 msc.legacyurl: /mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application msc.type: authoredcontent --- -Updating Related Data with the Entity Framework in an ASP.NET MVC Application -==================== -by [Tom Dykstra](https://github.com/tdykstra) -[Download Completed Project](http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8) +# Tutorial: Update related data with EF in an ASP.NET MVC app -> The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio. For information about the tutorial series, see [the first tutorial in the series](creating-an-entity-framework-data-model-for-an-asp-net-mvc-application.md). - - -In the previous tutorial you displayed related data; in this tutorial you'll update related data. For most relationships, this can be done by updating either foreign key fields or navigation properties. For many-to-many relationships, the Entity Framework doesn't expose the join table directly, so you add and remove entities to and from the appropriate navigation properties. +In the previous tutorial you displayed related data. In this tutorial you'll update related data. For most relationships, this can be done by updating either foreign key fields or navigation properties. For many-to-many relationships, the Entity Framework doesn't expose the join table directly, so you add and remove entities to and from the appropriate navigation properties. The following illustrations show some of the pages that you'll work with. @@ -28,7 +23,20 @@ The following illustrations show some of the pages that you'll work with. ![Instructor edit with courses](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png) -## Customize the Create and Edit Pages for Courses +In this tutorial, you: + +> [!div class="checklist"] +> * Customize courses pages +> * Add office to instructors page +> * Add courses to instructors page +> * Update DeleteConfirmed +> * Add office location and courses to the Create page + +## Prerequisites + +* [Reading Related Data](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md) + +## Customize courses pages When a new course entity is created, it must have a relationship to an existing department. To facilitate this, the scaffolded code includes controller methods and Create and Edit views that include a drop-down list for selecting the department. The drop-down list sets the `Course.DepartmentID` foreign key property, and that's all the Entity Framework needs in order to load the `Department` navigation property with the appropriate `Department` entity. You'll use the scaffolded code, but change it slightly to add error handling and sort the drop-down list. @@ -76,19 +84,20 @@ In *Views\Course\Delete.cshtml* and *Views\Course\Details.cshtml*, change the de Run the **Create** page (display the Course Index page and click **Create New**) and enter data for a new course: -![Course_create_page](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png) +| Value | Setting | +| ----- | ------- | +| Number | Enter *1000*. | +| Title | Enter *Algebra*. | +| Credits | Enter *4*. | +|Department | Select **Mathematics**. | Click **Create**. The Course Index page is displayed with the new course added to the list. The department name in the Index page list comes from the navigation property, showing that the relationship was established correctly. -![Course_Index_page_showing_new_course](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png) - Run the **Edit** page (display the Course Index page and click **Edit** on a course). -![Course_edit_page](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png) - Change data on the page and click **Save**. The Course Index page is displayed with the updated course data. -## Adding an Edit Page for Instructors +## Add office to instructors page When you edit an instructor record, you want to be able to update the instructor's office assignment. The `Instructor` entity has a one-to-zero-or-one relationship with the `OfficeAssignment` entity, which means you must handle the following situations: @@ -110,7 +119,7 @@ Replace the `HttpPost` `Edit` method with the following code. which handles offi [!code-csharp[Main](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/samples/sample11.cs)] -The reference to `RetryLimitExceededException` requires a `using` statement; to add it, right-click `RetryLimitExceededException`, and then click **Resolve** - **using System.Data.Entity.Infrastructure**. +The reference to `RetryLimitExceededException` requires a `using` statement. To add it, hover over `RetryLimitExceededException`. An explanation of the issue appears. Select **Show potential fixes** and then click **using System.Data.Entity.Infrastructure;**. ![Resolve Retry exception](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png) @@ -132,13 +141,9 @@ In *Views\Instructor\Edit.cshtml*, after the `div` elements for the **Hire Date* Run the page (select the **Instructors** tab and then click **Edit** on an instructor). Change the **Office Location** and click **Save**. -![Changing_the_office_location](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png) - -## Adding Course Assignments to the Instructor Edit Page +## Add courses to instructors page -Instructors may teach any number of courses. Now you'll enhance the Instructor Edit page by adding the ability to change course assignments using a group of check boxes, as shown in the following screen shot: - -![Instructor_edit_page_with_courses](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png) +Instructors may teach any number of courses. Now you'll enhance the Instructor Edit page by adding the ability to change course assignments using a group of check boxes. The relationship between the `Course` and `Instructor` entities is many-to-many, which means you do not have direct access to the foreign key properties which are in the join table. Instead, you add and remove entities to and from the `Instructor.Courses` navigation property. @@ -198,20 +203,15 @@ Then add a new detail cell immediately following the office location detail cell [!code-cshtml[Main](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/samples/sample23.cshtml?highlight=7-14)] -Run the **Instructor Index** page to see the courses assigned to each instructor: - -![Instructor_index_page](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png) +Run the **Instructor Index** page to see the courses assigned to each instructor. Click **Edit** on an instructor to see the Edit page. -![Instructor_edit_page_with_courses](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png) - Change some course assignments and click **Save**. The changes you make are reflected on the Index page. Note: The approach taken here to edit instructor course data works well when there is a limited number of courses. For collections that are much larger, a different UI and a different updating method would be required. - -## Update the DeleteConfirmed Method +## Update DeleteConfirmed In *InstructorController.cs*, delete the `DeleteConfirmed` method and insert the following code in its place. @@ -252,21 +252,31 @@ After you paste the code, fix line breaks and indentation as you did earlier for Run the Create page and add an instructor. -![Instructor Create with Courses](updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png) - -## Handling Transactions + +## Handling transactions As explained in the [Basic CRUD Functionality tutorial](implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application.md), by default the Entity Framework implicitly implements transactions. For scenarios where you need more control -- for example, if you want to include operations done outside of Entity Framework in a transaction -- see [Working with Transactions](https://msdn.microsoft.com/data/dn456843) on MSDN. -## Summary +## Get the code -You have now completed this introduction to working with related data. So far in these tutorials you've worked with code that does synchronous I/O. You can make the application use web server resources more efficiently by implementing asynchronous code, and that's what you'll do in the next tutorial. +[Download the Completed Project](https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip) -Please leave feedback on how you liked this tutorial and what we could improve. +## Additional resources Links to other Entity Framework resources can be found in [ASP.NET Data Access - Recommended Resources](../../../../whitepapers/aspnet-data-access-content-map.md). -> [!div class="step-by-step"] -> [Previous](reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application.md) -> [Next](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md) +## Next step + +In this tutorial, you: + +> [!div class="checklist"] +> * Customized courses pages +> * Added office to instructors page +> * Added courses to instructors page +> * Updated DeleteConfirmed +> * Added office location and courses to the Create page + +Advance to the next article to learn how to implement an asynchronous programming model. +> [!div class="nextstepaction"] +> [Asynchronous programming model](async-and-stored-procedures-with-the-entity-framework-in-an-asp-net-mvc-application.md) diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png index fa549744442f..a711f68a50a7 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image1.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png deleted file mode 100644 index fe9ede65e4b5..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image10.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png deleted file mode 100644 index a0f00cc83b54..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image11.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png deleted file mode 100644 index 76cd8ad85392..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image12.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png index 6d680684912f..32d40c64c8b6 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image2.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png index a0f00cc83b54..4f53d89ae048 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image3.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png deleted file mode 100644 index fa549744442f..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image4.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png deleted file mode 100644 index d9d974388feb..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image5.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png deleted file mode 100644 index 6d680684912f..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image6.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png index 97f6789f00ca..8b20e4c9f742 100644 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png and b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image7.png differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png deleted file mode 100644 index 1205dd94180b..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image8.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png b/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png deleted file mode 100644 index a0f00cc83b54..000000000000 Binary files a/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application/_static/image9.png and /dev/null differ diff --git a/aspnet/mvc/overview/getting-started/introduction/adding-a-view.md b/aspnet/mvc/overview/getting-started/introduction/adding-a-view.md index c990597f4312..1dc17444e474 100644 --- a/aspnet/mvc/overview/getting-started/introduction/adding-a-view.md +++ b/aspnet/mvc/overview/getting-started/introduction/adding-a-view.md @@ -3,7 +3,7 @@ title: Adding a View to an MVC app author: Rick-Anderson description: Adding a view to an MVC app ms.author: riande -ms.date: 09/1721/2017 +ms.date: 01/23/2019 uid: mvc/overview/getting-started/introduction/adding-a-view --- Adding a View @@ -54,7 +54,7 @@ Alternatively, run the application and browse to the `HelloWorld` controller (`h ![](adding-a-view/_static/image6.png) -Looks pretty good. However, notice that the browser's title bar shows "Index - My ASP.NET Appli" and the big link on the top of the page says "Application name." Depending on how small you make your browser window, you might need to click the three bars in the upper right to see the to the **Home**, **About**, **Contact**, **Register** and **Log in** links. +Looks pretty good. However, notice that the browser's title bar shows "Index - My ASP.NET Application," and the big link at the top of the page says "Application name." Depending on how small you make your browser window, you might need to click the three bars in the upper right to see the to the **Home**, **About**, **Contact**, **Register** and **Log in** links. ## Changing Views and Layout Pages diff --git a/aspnet/mvc/overview/older-versions-1/views/asp-net-mvc-views-overview-cs.md b/aspnet/mvc/overview/older-versions-1/views/asp-net-mvc-views-overview-cs.md index cb94d8c35141..e321f20413b9 100644 --- a/aspnet/mvc/overview/older-versions-1/views/asp-net-mvc-views-overview-cs.md +++ b/aspnet/mvc/overview/older-versions-1/views/asp-net-mvc-views-overview-cs.md @@ -22,7 +22,7 @@ The purpose of this tutorial is to provide you with a brief introduction to ASP. For ASP.NET or Active Server Pages, ASP.NET MVC does not include anything that directly corresponds to a page. In an ASP.NET MVC application, there is not a page on disk that corresponds to the path in the URL that you type into the address bar of your browser. The closest thing to a page in an ASP.NET MVC application is something called a *view*. -ASP.NET MVC application, incoming browser requests are mapped to controller actions. A controller action might return a view. However, a controller action might perform some other type of action such as redirecting you to another controller action. +In an ASP.NET MVC application, incoming browser requests are mapped to controller actions. A controller action might return a view. However, a controller action might perform some other type of action such as redirecting you to another controller action. Listing 1 contains a simple controller named the HomeController. The HomeController exposes two controller actions named Index() and Details(). @@ -85,7 +85,7 @@ Since you call Response.Write() so often, Microsoft provides you with a shortcut [!code-aspx[Main](asp-net-mvc-views-overview-cs/samples/sample3.aspx)] -You can use any .NET language to generate dynamic content in a view. Normally, you�ll use either Visual Basic .NET or C# to write your controllers and views. +You can use any .NET language to generate dynamic content in a view. Normally, you'll use either Visual Basic .NET or C# to write your controllers and views. ## Using HTML Helpers to Generate View Content @@ -133,7 +133,7 @@ The view in Listing 7 retrieves the message from the view data and renders the m Notice that the view takes advantage of the Html.Encode() HTML Helper method when rendering the message. The Html.Encode() HTML Helper encodes special characters such as < and > into characters that are safe to display in a web page. Whenever you render content that a user submits to a website, you should encode the content to prevent JavaScript injection attacks. -(Because we created the message ourselves in the ProductController, we don�t really need to encode the message. However, it is a good habit to always call the Html.Encode() method when displaying content retrieved from view data within a view.) +(Because we created the message ourselves in the ProductController, we don't really need to encode the message. However, it is a good habit to always call the Html.Encode() method when displaying content retrieved from view data within a view.) In Listing 7, we took advantage of view data to pass a simple string message from a controller to a view. You also can use view data to pass other types of data, such as a collection of database records, from a controller to a view. For example, if you want to display the contents of the Products database table in a view, then you would pass the collection of database records in view data. diff --git a/aspnet/mvc/overview/views/using-page-inspector-in-aspnet-mvc.md b/aspnet/mvc/overview/views/using-page-inspector-in-aspnet-mvc.md index 776363939f92..45f613a77d0d 100644 --- a/aspnet/mvc/overview/views/using-page-inspector-in-aspnet-mvc.md +++ b/aspnet/mvc/overview/views/using-page-inspector-in-aspnet-mvc.md @@ -155,7 +155,7 @@ In the Page Inspector browser window, move the mouse pointer over the "Home Page ![Hovering over div.content-wrapper](using-page-inspector-in-aspnet-mvc/_static/image26.png) -Click within the div.content-wrapper section once, and then move the mouse pointer to the **Styles** window. The **Syles** window shows all of the CSS rules for this element. Scroll down to find the .featured .content-wrapper class selector. Now clear the checkbox for the background-color property. +Click within the div.content-wrapper section once, and then move the mouse pointer to the **Styles** window. The **Styles** window shows all of the CSS rules for this element. Scroll down to find the .featured .content-wrapper class selector. Now clear the checkbox for the background-color property. ![Clear background color](using-page-inspector-in-aspnet-mvc/_static/image28.png) @@ -180,7 +180,7 @@ Click **Inspect** to put Page Inspector in Inspection Mode. In the Page Inspector browser, move the mouse pointer over the "Home Page" section until the **div.content-wrapper** label appears. Click once to select this element. -The **Syles** window shows all of the CSS rules for this element. Scroll down to find the .featured .content-wrapper class selector. Click on ".featured .content-wrapper". Page Inspector opens the CSS file that defines this style (Site.css) and highlights the corresponding CSS style. +The **Styles** window shows all of the CSS rules for this element. Scroll down to find the .featured .content-wrapper class selector. Click on ".featured .content-wrapper". Page Inspector opens the CSS file that defines this style (Site.css) and highlights the corresponding CSS style. ![](using-page-inspector-in-aspnet-mvc/_static/image32.png) diff --git a/aspnet/signalr/index.md b/aspnet/signalr/index.md index 360869abccb6..2b9271476249 100644 --- a/aspnet/signalr/index.md +++ b/aspnet/signalr/index.md @@ -1,9 +1,9 @@ --- uid: signalr/index title: "SignalR | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "Microsoft ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of adding real-time web functionality to your applications." -ms.author: riande +ms.author: bradyg ms.date: 10/24/2012 ms.assetid: 282a521f-2b86-4fac-bcf6-b6d5e0fe969c msc.legacyurl: /signalr diff --git a/aspnet/signalr/overview/advanced/dependency-injection.md b/aspnet/signalr/overview/advanced/dependency-injection.md index 607fcfec0651..2e8620ea19fd 100644 --- a/aspnet/signalr/overview/advanced/dependency-injection.md +++ b/aspnet/signalr/overview/advanced/dependency-injection.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/advanced/dependency-injection title: "Dependency Injection in SignalR | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "Software versions used in this topic Visual Studio 2013 .NET 4.5 SignalR version 2 Previous versions of this topic For information about earlier versions of..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: a14121ae-02cf-4024-8af0-9dd0dc810690 msc.legacyurl: /signalr/overview/advanced/dependency-injection diff --git a/aspnet/signalr/overview/advanced/index.md b/aspnet/signalr/overview/advanced/index.md index ca900efa3f6e..19b9297bf27d 100644 --- a/aspnet/signalr/overview/advanced/index.md +++ b/aspnet/signalr/overview/advanced/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/advanced/index title: "SignalR Advanced Topics | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "SignalR documentation - advanced topics." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: d8f5d0e8-1ddd-4005-a7aa-50ae87f9f9f3 msc.legacyurl: /signalr/overview/advanced diff --git a/aspnet/signalr/overview/deployment/index.md b/aspnet/signalr/overview/deployment/index.md index 991cdcfecbf2..38cec5c69bf2 100644 --- a/aspnet/signalr/overview/deployment/index.md +++ b/aspnet/signalr/overview/deployment/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/deployment/index title: "SignalR Deployment and Hosting | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "How to deploy and host SignalR applications." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: 62482bdd-e2a4-46e5-b909-6d0c6bc07114 msc.legacyurl: /signalr/overview/deployment diff --git a/aspnet/signalr/overview/deployment/tutorial-signalr-self-host.md b/aspnet/signalr/overview/deployment/tutorial-signalr-self-host.md index a2a1744456c7..b03937f1ce6c 100644 --- a/aspnet/signalr/overview/deployment/tutorial-signalr-self-host.md +++ b/aspnet/signalr/overview/deployment/tutorial-signalr-self-host.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/deployment/tutorial-signalr-self-host title: "Tutorial: SignalR Self-Host | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This tutorial shows how to create a self-hosted SignalR 2 server, and how to connect to it with a JavaScript client. Software versions used in the tutorial V..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: 400db427-27af-4f2f-abf0-5486d5e024b5 msc.legacyurl: /signalr/overview/deployment/tutorial-signalr-self-host diff --git a/aspnet/signalr/overview/deployment/using-signalr-with-azure-web-sites.md b/aspnet/signalr/overview/deployment/using-signalr-with-azure-web-sites.md index 6c46ece64543..81482640684b 100644 --- a/aspnet/signalr/overview/deployment/using-signalr-with-azure-web-sites.md +++ b/aspnet/signalr/overview/deployment/using-signalr-with-azure-web-sites.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/deployment/using-signalr-with-azure-web-sites title: "Using SignalR with Web Apps in Azure App Service | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This document describes how to configure a SignalR application that runs on Microsoft Azure. Software versions used in the tutorial Visual Studio 2013 or Vis..." -ms.author: riande +ms.author: bradyg ms.date: 07/01/2015 ms.assetid: 2a7517a0-b88c-4162-ade3-9bf6ca7062fd msc.legacyurl: /signalr/overview/deployment/using-signalr-with-azure-web-sites diff --git a/aspnet/signalr/overview/getting-started/index.md b/aspnet/signalr/overview/getting-started/index.md index ce295869a0f7..2966647d49b7 100644 --- a/aspnet/signalr/overview/getting-started/index.md +++ b/aspnet/signalr/overview/getting-started/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/getting-started/index title: "SignalR Getting Started | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "Learn About ASP.NET SignalR ASP.NET SignalR is a new library for ASP.NET developers that makes developing real-time web functionality easy. SignalR allows bi..." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: 2acff246-c74c-4277-b539-35bc42988c6f msc.legacyurl: /signalr/overview/getting-started diff --git a/aspnet/signalr/overview/getting-started/introduction-to-signalr.md b/aspnet/signalr/overview/getting-started/introduction-to-signalr.md index f29cc0522445..4fc6aa1bfcdb 100644 --- a/aspnet/signalr/overview/getting-started/introduction-to-signalr.md +++ b/aspnet/signalr/overview/getting-started/introduction-to-signalr.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/getting-started/introduction-to-signalr title: "Introduction to SignalR | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This article describes what SignalR is, and some of the solutions it was designed to create." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: 0fab5e35-8c1f-43d4-8635-b8aba8766a71 msc.legacyurl: /signalr/overview/getting-started/introduction-to-signalr diff --git a/aspnet/signalr/overview/getting-started/real-time-web-applications-with-signalr.md b/aspnet/signalr/overview/getting-started/real-time-web-applications-with-signalr.md index dbc2430a3d15..59d8a494fd2b 100644 --- a/aspnet/signalr/overview/getting-started/real-time-web-applications-with-signalr.md +++ b/aspnet/signalr/overview/getting-started/real-time-web-applications-with-signalr.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/getting-started/real-time-web-applications-with-signalr title: "Hands On Lab: Real-Time Web Applications with SignalR | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "Real-time Web applications feature the ability to push server-side content to the connected clients as it happens, in real-time. For ASP.NET developers, ASP...." -ms.author: riande +ms.author: bradyg ms.date: 07/16/2014 ms.assetid: ba07958c-42e1-4da0-81db-ba6925ed6db0 msc.legacyurl: /signalr/overview/getting-started/real-time-web-applications-with-signalr diff --git a/aspnet/signalr/overview/getting-started/supported-platforms.md b/aspnet/signalr/overview/getting-started/supported-platforms.md index c9ca43877713..4b1dfe8cf502 100644 --- a/aspnet/signalr/overview/getting-started/supported-platforms.md +++ b/aspnet/signalr/overview/getting-started/supported-platforms.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/getting-started/supported-platforms title: "Supported Platforms | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This article describes what clients and servers are supported by SignalR." -ms.author: riande +ms.author: bradyg ms.date: 04/18/2018 ms.assetid: eac31beb-0f46-4afa-9def-e80904dea4f0 msc.legacyurl: /signalr/overview/getting-started/supported-platforms diff --git a/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc.md b/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc.md index 0472a17c6f18..9a130eb0ce76 100644 --- a/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc.md +++ b/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc.md @@ -1,10 +1,10 @@ --- uid: signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc title: "Tutorial: Real-time chat with SignalR 2 and MVC 5 | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This tutorial shows how to use ASP.NET SignalR 2 to create a real-time chat application. You add SignalR to an MVC 5 application." -ms.author: riande -ms.date: 01/02/2019 +ms.author: bradyg +ms.date: 01/22/2019 ms.assetid: 80bfe5fb-bdfc-41fe-ac43-2132e5d69fac msc.legacyurl: /signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc msc.type: authoredcontent @@ -171,6 +171,10 @@ This code opens a connection with the hub. The code starts the connection and then passes it a function to handle the click event on the **Send** button in the Chat page. +## Get the code + +[Download Completed Project](http://code.msdn.microsoft.com/Getting-Started-with-c366b2f3) + ## Additional resources For more about SignalR, see the following resources: diff --git a/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr.md b/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr.md index 15ee806ad8d0..e36232218563 100644 --- a/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr.md +++ b/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr.md @@ -1,10 +1,10 @@ --- uid: signalr/overview/getting-started/tutorial-getting-started-with-signalr title: "Tutorial: Real-time chat with SignalR 2 | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This tutorial shows how to use SignalR to create a real-time chat application. You add SignalR to an empty ASP.NET web application." -ms.author: riande -ms.date: 01/02/2019 +ms.author: bradyg +ms.date: 01/22/2019 ms.assetid: a8b3b778-f009-4369-85c7-e90f9878d8b4 msc.legacyurl: /signalr/overview/getting-started/tutorial-getting-started-with-signalr msc.type: authoredcontent @@ -157,6 +157,10 @@ This code opens a connection with the hub. The code starts the connection and then passes it a function to handle the click event on the **Send** button in the HTML page. +## Get the code + +[Download Completed Project](http://code.msdn.microsoft.com/SignalR-Getting-Started-b9d18aa9) + ## Additional resources For more about SignalR, see the following resources: diff --git a/aspnet/signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr.md b/aspnet/signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr.md index 4b7c23501c39..78e2b5dd6eea 100644 --- a/aspnet/signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr.md +++ b/aspnet/signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr.md @@ -1,10 +1,10 @@ --- uid: signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr title: "Tutorial: Create high-frequency real-time app with SignalR 2 | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This tutorial shows how to create a web application that uses ASP.NET SignalR to provide high-frequency messaging functionality." -ms.author: riande -ms.date: 01/02/2019 +ms.author: bradyg +ms.date: 01/22/2019 ms.assetid: 9f969dda-78ea-4329-b1e3-e51c02210a2b msc.legacyurl: /signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr msc.type: authoredcontent @@ -219,6 +219,10 @@ The movement of the shape in the other window appears less jerky. The app interp This code moves the shape from the old location to the new one. The server gives the position of the shape over the course of the animation interval. In this case, that's 100 milliseconds. The app clears any previous animation running on the shape before the new animation starts. +## Get the code + +[Download Completed Project](http://code.msdn.microsoft.com/SignalR-20-MoveShape-Demo-6285b83a) + ## Additional resources The communication paradigm you just learned about is useful for developing online games and other simulations, like [the ShootR game created with SignalR](https://shootr.azurewebsites.net/). diff --git a/aspnet/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr.md b/aspnet/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr.md index 4d3eb8e722e2..59b81eefeec8 100644 --- a/aspnet/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr.md +++ b/aspnet/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr.md @@ -3,7 +3,7 @@ uid: signalr/overview/getting-started/tutorial-server-broadcast-with-signalr title: "Tutorial: Server broadcast with SignalR 2 | Microsoft Docs" author: tdykstra description: "This tutorial shows how to create a web application that uses ASP.NET SignalR 2 to provide server broadcast functionality." -ms.author: riande +ms.author: bradyg ms.date: 01/02/2019 ms.topic: tutorial ms.assetid: 1568247f-60b5-4eca-96e0-e661fbb2b273 diff --git a/aspnet/signalr/overview/guide-to-the-api/handling-connection-lifetime-events.md b/aspnet/signalr/overview/guide-to-the-api/handling-connection-lifetime-events.md index c1fc53be8773..7c446d40b583 100644 --- a/aspnet/signalr/overview/guide-to-the-api/handling-connection-lifetime-events.md +++ b/aspnet/signalr/overview/guide-to-the-api/handling-connection-lifetime-events.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/guide-to-the-api/handling-connection-lifetime-events title: "Understanding and Handling Connection Lifetime Events in SignalR | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This article describes how to use the events exposed by the Hubs API." -ms.author: riande +ms.author: bradyg ms.date: 01/15/2019 ms.assetid: 03960de2-8d95-4444-9169-4426dcc64913 msc.legacyurl: /signalr/overview/guide-to-the-api/handling-connection-lifetime-events diff --git a/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client.md b/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client.md index 04ebadb39feb..cf023e435884 100644 --- a/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client.md +++ b/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client title: "ASP.NET SignalR Hubs API Guide - JavaScript Client | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This document provides an introduction to using the Hubs API for SignalR version 2 in JavaScript clients, such as browsers and Windows Store (WinJS) applicat..." -ms.author: riande +ms.author: bradyg ms.date: 01/15/2019 ms.assetid: a9fd4dc0-1b96-4443-82ca-932a5b4a8ea4 msc.legacyurl: /signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client diff --git a/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-net-client.md b/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-net-client.md index 8a0824898070..8dd3eae624bf 100644 --- a/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-net-client.md +++ b/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-net-client.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/guide-to-the-api/hubs-api-guide-net-client title: "ASP.NET SignalR Hubs API Guide - .NET Client (C#) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This document provides an introduction to using the Hubs API for SignalR version 2 in .NET clients, such as Windows Store (WinRT), WPF, Silverlight, and cons..." -ms.author: riande +ms.author: bradyg ms.date: 01/15/2019 ms.assetid: 6d02d9f7-94e5-4140-9f51-5a6040f274f6 msc.legacyurl: /signalr/overview/guide-to-the-api/hubs-api-guide-net-client diff --git a/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server.md b/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server.md index 8a140a97b992..1c14df82e335 100644 --- a/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server.md +++ b/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/guide-to-the-api/hubs-api-guide-server title: "ASP.NET SignalR Hubs API Guide - Server (C#) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This document provides an introduction to programming the server side of the ASP.NET SignalR Hubs API for SignalR version 2, with code samples demonstrating..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: b19913e5-cd8a-4e4b-a872-5ac7a858a934 msc.legacyurl: /signalr/overview/guide-to-the-api/hubs-api-guide-server diff --git a/aspnet/signalr/overview/guide-to-the-api/index.md b/aspnet/signalr/overview/guide-to-the-api/index.md index c28b2529feed..9fe0fe2e1762 100644 --- a/aspnet/signalr/overview/guide-to-the-api/index.md +++ b/aspnet/signalr/overview/guide-to-the-api/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/guide-to-the-api/index title: "SignalR Guide to the API | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "Documentation on how to use the SignalR Hubs API. For authorization API, see the Security tab." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: af69e8d2-efdd-4d0b-9bbc-95353a65c0db msc.legacyurl: /signalr/overview/guide-to-the-api diff --git a/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections.md b/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections.md index 209d953e4e68..12c0fe148b55 100644 --- a/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections.md +++ b/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/guide-to-the-api/mapping-users-to-connections title: "Mapping SignalR Users to Connections | Microsoft Docs" -author: Rick-Anderson +author: bradygaster description: "This topic shows how to retain information about users and their connections. Patrick Fletcher helped write this topic. Software versions used in this topic..." -ms.author: riande +ms.author: bradyg ms.date: 12/30/2014 ms.assetid: f80c08b1-3f1f-432c-980c-c7b6edeb31b1 msc.legacyurl: /signalr/overview/guide-to-the-api/mapping-users-to-connections diff --git a/aspnet/signalr/overview/guide-to-the-api/working-with-groups.md b/aspnet/signalr/overview/guide-to-the-api/working-with-groups.md index 1a33402ba86b..4db5263b1139 100644 --- a/aspnet/signalr/overview/guide-to-the-api/working-with-groups.md +++ b/aspnet/signalr/overview/guide-to-the-api/working-with-groups.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/guide-to-the-api/working-with-groups title: "Working with Groups in SignalR | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic describes how to persist group membership information with the Hub API." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: cd378ecd-3e9e-4236-b902-65916d85a048 msc.legacyurl: /signalr/overview/guide-to-the-api/working-with-groups diff --git a/aspnet/signalr/overview/index.md b/aspnet/signalr/overview/index.md index 9b67325d10af..4700e9740f3b 100644 --- a/aspnet/signalr/overview/index.md +++ b/aspnet/signalr/overview/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/index title: "SignalR Guidance | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "" -ms.author: riande +ms.author: bradyg ms.date: 10/24/2012 ms.assetid: e57da75a-1d98-4e3c-8787-f1d7e1eb2d86 msc.legacyurl: /signalr/overview diff --git a/aspnet/signalr/overview/older-versions/dependency-injection.md b/aspnet/signalr/overview/older-versions/dependency-injection.md index 9c06560908a6..7166c64bd52e 100644 --- a/aspnet/signalr/overview/older-versions/dependency-injection.md +++ b/aspnet/signalr/overview/older-versions/dependency-injection.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/dependency-injection title: "Dependency Injection in SignalR 1.x | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "" -ms.author: riande +ms.author: bradyg ms.date: 05/15/2013 ms.assetid: eaa206c4-edb3-487e-8fcb-54a3261fed36 msc.legacyurl: /signalr/overview/older-versions/dependency-injection diff --git a/aspnet/signalr/overview/older-versions/handling-connection-lifetime-events.md b/aspnet/signalr/overview/older-versions/handling-connection-lifetime-events.md index 9056a9caefcc..d7ac831f08b8 100644 --- a/aspnet/signalr/overview/older-versions/handling-connection-lifetime-events.md +++ b/aspnet/signalr/overview/older-versions/handling-connection-lifetime-events.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/handling-connection-lifetime-events title: "Understanding and Handling Connection Lifetime Events in SignalR 1.x | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This article describes how to use the events exposed by the Hubs API." -ms.author: riande +ms.author: bradyg ms.date: 06/05/2013 ms.assetid: e608e263-264d-448b-b0eb-6eeb77713b22 msc.legacyurl: /signalr/overview/older-versions/handling-connection-lifetime-events diff --git a/aspnet/signalr/overview/older-versions/hub-authorization.md b/aspnet/signalr/overview/older-versions/hub-authorization.md index 5f11ee21ac0e..6e4dfbc2b7dc 100644 --- a/aspnet/signalr/overview/older-versions/hub-authorization.md +++ b/aspnet/signalr/overview/older-versions/hub-authorization.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/hub-authorization title: "Authentication and Authorization for SignalR Hubs (SignalR 1.x) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic describes how to restrict which users or roles can access hub methods." -ms.author: riande +ms.author: bradyg ms.date: 10/17/2013 ms.assetid: 3d2dfc0e-eac2-4076-a468-325d3d01cc7b msc.legacyurl: /signalr/overview/older-versions/hub-authorization diff --git a/aspnet/signalr/overview/older-versions/index.md b/aspnet/signalr/overview/older-versions/index.md index e6516e367034..da47c3b36ecf 100644 --- a/aspnet/signalr/overview/older-versions/index.md +++ b/aspnet/signalr/overview/older-versions/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/index title: "SignalR Older Versions | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "Documentation that pertains to earlier versions of SignalR." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: 607f4617-380f-41fa-bf46-147e82bb8124 msc.legacyurl: /signalr/overview/older-versions diff --git a/aspnet/signalr/overview/older-versions/introduction-to-security.md b/aspnet/signalr/overview/older-versions/introduction-to-security.md index d99970af3ab4..fa8dcaf0760a 100644 --- a/aspnet/signalr/overview/older-versions/introduction-to-security.md +++ b/aspnet/signalr/overview/older-versions/introduction-to-security.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/introduction-to-security title: "Introduction to SignalR Security (SignalR 1.x) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "Describes the security issues you must consider when developing a SignalR application." -ms.author: riande +ms.author: bradyg ms.date: 10/17/2013 ms.assetid: 715a4059-d307-4631-abbb-c789c95d6eb4 msc.legacyurl: /signalr/overview/older-versions/introduction-to-security diff --git a/aspnet/signalr/overview/older-versions/mapping-users-to-connections.md b/aspnet/signalr/overview/older-versions/mapping-users-to-connections.md index 56e55d055a53..2135ba2a3bdd 100644 --- a/aspnet/signalr/overview/older-versions/mapping-users-to-connections.md +++ b/aspnet/signalr/overview/older-versions/mapping-users-to-connections.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/mapping-users-to-connections title: "Mapping SignalR Users to Connections in SignalR 1.x | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic shows how to retain information about users and their connections." -ms.author: riande +ms.author: bradyg ms.date: 10/17/2013 ms.assetid: ebbc93a8-e6c4-4122-8e0d-3aa42293c747 msc.legacyurl: /signalr/overview/older-versions/mapping-users-to-connections diff --git a/aspnet/signalr/overview/older-versions/persistent-connection-authorization.md b/aspnet/signalr/overview/older-versions/persistent-connection-authorization.md index 74e363b0de1c..b70fcbeeae79 100644 --- a/aspnet/signalr/overview/older-versions/persistent-connection-authorization.md +++ b/aspnet/signalr/overview/older-versions/persistent-connection-authorization.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/persistent-connection-authorization title: "Authentication and Authorization for SignalR Persistent Connections (SignalR 1.x) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic describes how to enforce authorization on a persistent connection. For general information about integrating security into a SignalR application,..." -ms.author: riande +ms.author: bradyg ms.date: 10/21/2013 ms.assetid: c34bc627-41af-4c21-a817-e97a19a7f252 msc.legacyurl: /signalr/overview/older-versions/persistent-connection-authorization diff --git a/aspnet/signalr/overview/older-versions/scaleout-in-signalr.md b/aspnet/signalr/overview/older-versions/scaleout-in-signalr.md index 2bbd07de3758..270166292ba5 100644 --- a/aspnet/signalr/overview/older-versions/scaleout-in-signalr.md +++ b/aspnet/signalr/overview/older-versions/scaleout-in-signalr.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/scaleout-in-signalr title: "Introduction to Scaleout in SignalR 1.x | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "" -ms.author: riande +ms.author: bradyg ms.date: 04/29/2013 ms.assetid: 3fd9f11c-799b-4001-bd60-1e70cfc61c19 msc.legacyurl: /signalr/overview/older-versions/scaleout-in-signalr diff --git a/aspnet/signalr/overview/older-versions/scaleout-with-redis.md b/aspnet/signalr/overview/older-versions/scaleout-with-redis.md index 1545072636c3..711271756221 100644 --- a/aspnet/signalr/overview/older-versions/scaleout-with-redis.md +++ b/aspnet/signalr/overview/older-versions/scaleout-with-redis.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/scaleout-with-redis title: "SignalR Scaleout with Redis (SignalR 1.x) | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "" -ms.author: riande +ms.author: bradyg ms.date: 05/01/2013 ms.assetid: 6abecf80-8ffa-41ba-b0d9-1d9edbe7687b msc.legacyurl: /signalr/overview/older-versions/scaleout-with-redis diff --git a/aspnet/signalr/overview/older-versions/scaleout-with-sql-server.md b/aspnet/signalr/overview/older-versions/scaleout-with-sql-server.md index 79f916fad29d..91d3febf633e 100644 --- a/aspnet/signalr/overview/older-versions/scaleout-with-sql-server.md +++ b/aspnet/signalr/overview/older-versions/scaleout-with-sql-server.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/scaleout-with-sql-server title: "SignalR Scaleout with SQL Server (SignalR 1.x) | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "" -ms.author: riande +ms.author: bradyg ms.date: 05/01/2013 ms.assetid: 1dca7967-8296-444a-9533-837eb284e78c msc.legacyurl: /signalr/overview/older-versions/scaleout-with-sql-server diff --git a/aspnet/signalr/overview/older-versions/scaleout-with-windows-azure-service-bus.md b/aspnet/signalr/overview/older-versions/scaleout-with-windows-azure-service-bus.md index 7e53ab599834..826f8abaa980 100644 --- a/aspnet/signalr/overview/older-versions/scaleout-with-windows-azure-service-bus.md +++ b/aspnet/signalr/overview/older-versions/scaleout-with-windows-azure-service-bus.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/scaleout-with-windows-azure-service-bus title: "SignalR Scaleout with Azure Service Bus (SignalR 1.x) | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "" -ms.author: riande +ms.author: bradyg ms.date: 05/01/2013 ms.assetid: 501db899-e68c-49ff-81b2-1dc561bfe908 msc.legacyurl: /signalr/overview/older-versions/scaleout-with-windows-azure-service-bus diff --git a/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-javascript-client.md b/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-javascript-client.md index 32ea3ed1f17b..20d8cb8b887f 100644 --- a/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-javascript-client.md +++ b/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-javascript-client.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/signalr-1x-hubs-api-guide-javascript-client title: "SignalR 1.x Hubs API Guide - JavaScript Client | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This document provides an introduction to using the Hubs API for SignalR version 1.1 in JavaScript clients, such as browsers and Windows Store (WinJS) applic..." -ms.author: riande +ms.author: bradyg ms.date: 04/17/2013 ms.assetid: dcd4593b-1118-418a-af71-d12ff33fb36d msc.legacyurl: /signalr/overview/older-versions/signalr-1x-hubs-api-guide-javascript-client diff --git a/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-net-client.md b/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-net-client.md index 3016c0679f85..d9b17f18ee1b 100644 --- a/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-net-client.md +++ b/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-net-client.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/signalr-1x-hubs-api-guide-net-client title: "ASP.NET SignalR Hubs API Guide - .NET Client (SignalR 1.x) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This document provides an introduction to using the Hubs API for SignalR version 2 in .NET clients, such as Windows Store (WinRT), WPF, Silverlight, and cons..." -ms.author: riande +ms.author: bradyg ms.date: 04/17/2013 ms.assetid: c334adc3-d6dc-44f3-9f06-f7634475aad3 msc.legacyurl: /signalr/overview/older-versions/signalr-1x-hubs-api-guide-net-client diff --git a/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-server.md b/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-server.md index e273162a3769..4fa41832a3ac 100644 --- a/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-server.md +++ b/aspnet/signalr/overview/older-versions/signalr-1x-hubs-api-guide-server.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/signalr-1x-hubs-api-guide-server title: "ASP.NET SignalR Hubs API Guide - Server (SignalR 1.x) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This document provides an introduction to programming the server side of the ASP.NET SignalR Hubs API for SignalR version 1.1, with code samples demonstratin..." -ms.author: riande +ms.author: bradyg ms.date: 04/17/2013 ms.assetid: 03e4b9f5-0fea-4d94-959f-014b2762a301 msc.legacyurl: /signalr/overview/older-versions/signalr-1x-hubs-api-guide-server diff --git a/aspnet/signalr/overview/older-versions/signalr-performance.md b/aspnet/signalr/overview/older-versions/signalr-performance.md index 6abb896fdbff..f5a9acca68e4 100644 --- a/aspnet/signalr/overview/older-versions/signalr-performance.md +++ b/aspnet/signalr/overview/older-versions/signalr-performance.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/signalr-performance title: "SignalR Performance (SignalR 1.x) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "SignalR Performance" -ms.author: riande +ms.author: bradyg ms.date: 07/03/2013 ms.assetid: 9594d644-66b6-4223-acdd-23e29a6e4c46 msc.legacyurl: /signalr/overview/older-versions/signalr-performance diff --git a/aspnet/signalr/overview/older-versions/troubleshooting.md b/aspnet/signalr/overview/older-versions/troubleshooting.md index 917aecb9a464..c0833318b32d 100644 --- a/aspnet/signalr/overview/older-versions/troubleshooting.md +++ b/aspnet/signalr/overview/older-versions/troubleshooting.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/troubleshooting title: "SignalR Troubleshooting (SignalR 1.x) | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This article describes common issues with developing SignalR applications." -ms.author: riande +ms.author: bradyg ms.date: 06/05/2013 ms.assetid: 347210ba-c452-4feb-886f-b51d89f58971 msc.legacyurl: /signalr/overview/older-versions/troubleshooting diff --git a/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr-and-mvc-4.md b/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr-and-mvc-4.md index 50edab21d4a6..36a7e6847399 100644 --- a/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr-and-mvc-4.md +++ b/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr-and-mvc-4.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/tutorial-getting-started-with-signalr-and-mvc-4 title: "Tutorial: Getting Started with SignalR 1.x and MVC 4 | Microsoft Docs" -author: pfletcher +author: bradygaster description: "Use ASP.NET SignalR and ASP.NET MVC 4 to build a real-time chat application." -ms.author: riande +ms.author: bradyg ms.date: 03/29/2013 ms.assetid: eeef9f73-6de3-49f9-b50b-9af22108f2ce msc.legacyurl: /signalr/overview/older-versions/tutorial-getting-started-with-signalr-and-mvc-4 diff --git a/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr.md b/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr.md index a2d2c4f45636..64e1066cb295 100644 --- a/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr.md +++ b/aspnet/signalr/overview/older-versions/tutorial-getting-started-with-signalr.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/tutorial-getting-started-with-signalr title: "Tutorial: Getting Started with SignalR 1.x | Microsoft Docs" -author: pfletcher +author: bradygaster description: "Use ASP.NET SignalR to build a real-time chat application in an HTML page." -ms.author: riande +ms.author: bradyg ms.date: 02/18/2013 ms.assetid: fdc3599a-5217-44c1-951f-0eec9812dce7 msc.legacyurl: /signalr/overview/older-versions/tutorial-getting-started-with-signalr diff --git a/aspnet/signalr/overview/older-versions/tutorial-high-frequency-realtime-with-signalr.md b/aspnet/signalr/overview/older-versions/tutorial-high-frequency-realtime-with-signalr.md index ca726bef0fe0..b37b91c625ce 100644 --- a/aspnet/signalr/overview/older-versions/tutorial-high-frequency-realtime-with-signalr.md +++ b/aspnet/signalr/overview/older-versions/tutorial-high-frequency-realtime-with-signalr.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/tutorial-high-frequency-realtime-with-signalr title: "High-Frequency Realtime with SignalR 1.x | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This tutorial shows how to create a web application that uses ASP.NET SignalR to provide high-frequency messaging functionality. High-frequency messaging in..." -ms.author: riande +ms.author: bradyg ms.date: 04/16/2013 ms.assetid: ad2a5da5-2e79-40ea-bc84-028d327f5982 msc.legacyurl: /signalr/overview/older-versions/tutorial-high-frequency-realtime-with-signalr diff --git a/aspnet/signalr/overview/older-versions/tutorial-server-broadcast-with-aspnet-signalr.md b/aspnet/signalr/overview/older-versions/tutorial-server-broadcast-with-aspnet-signalr.md index 590ceaf13974..406e9156a5bc 100644 --- a/aspnet/signalr/overview/older-versions/tutorial-server-broadcast-with-aspnet-signalr.md +++ b/aspnet/signalr/overview/older-versions/tutorial-server-broadcast-with-aspnet-signalr.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/tutorial-server-broadcast-with-aspnet-signalr title: "Tutorial: Server Broadcast with ASP.NET SignalR 1.x | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This tutorial shows how to create a web application that uses ASP.NET SignalR to provide server broadcast functionality. Server broadcast means that communic..." -ms.author: riande +ms.author: bradyg ms.date: 04/10/2013 ms.assetid: ab7b2554-956a-4f6d-b2a0-4ae0c62e8580 msc.legacyurl: /signalr/overview/older-versions/tutorial-server-broadcast-with-aspnet-signalr diff --git a/aspnet/signalr/overview/older-versions/working-with-groups.md b/aspnet/signalr/overview/older-versions/working-with-groups.md index ec2ee64e4a7e..0a0e9e984e1b 100644 --- a/aspnet/signalr/overview/older-versions/working-with-groups.md +++ b/aspnet/signalr/overview/older-versions/working-with-groups.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/older-versions/working-with-groups title: "Working with Groups in SignalR 1.x | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic describes how to persist group membership information with the Hub API." -ms.author: riande +ms.author: bradyg ms.date: 10/21/2013 ms.assetid: 22929efd-68c9-4609-b76d-f8ba42fda01e msc.legacyurl: /signalr/overview/older-versions/working-with-groups diff --git a/aspnet/signalr/overview/performance/index.md b/aspnet/signalr/overview/performance/index.md index 671de05ffc4b..7027518b9731 100644 --- a/aspnet/signalr/overview/performance/index.md +++ b/aspnet/signalr/overview/performance/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/performance/index title: "SignalR Performance | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "How to maximize the performance of SignalR applications." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: fda81611-b67b-4c62-915e-8adc1924a401 msc.legacyurl: /signalr/overview/performance diff --git a/aspnet/signalr/overview/performance/scaleout-in-signalr.md b/aspnet/signalr/overview/performance/scaleout-in-signalr.md index 7992cf1b7a48..d38423e022b0 100644 --- a/aspnet/signalr/overview/performance/scaleout-in-signalr.md +++ b/aspnet/signalr/overview/performance/scaleout-in-signalr.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/performance/scaleout-in-signalr title: "Introduction to Scaleout in SignalR | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "Software versions used in this topic Visual Studio 2013 .NET 4.5 SignalR version 2 Previous versions of this topic For information about earlier versions of..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: 7e781fc1-1c1f-45a8-bc1d-338e96dbe9c9 msc.legacyurl: /signalr/overview/performance/scaleout-in-signalr diff --git a/aspnet/signalr/overview/performance/scaleout-with-redis.md b/aspnet/signalr/overview/performance/scaleout-with-redis.md index ff349277883c..bc0348898fb5 100644 --- a/aspnet/signalr/overview/performance/scaleout-with-redis.md +++ b/aspnet/signalr/overview/performance/scaleout-with-redis.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/performance/scaleout-with-redis title: "SignalR Scaleout with Redis | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "Software versions used in this topic Visual Studio 2013 .NET 4.5 SignalR version 2 Previous versions of this topic For information about earlier versions of..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: 6ecd08c1-e364-4cd7-ad4c-806521911585 msc.legacyurl: /signalr/overview/performance/scaleout-with-redis diff --git a/aspnet/signalr/overview/performance/scaleout-with-sql-server.md b/aspnet/signalr/overview/performance/scaleout-with-sql-server.md index ac94f61c90eb..d191f1e95bef 100644 --- a/aspnet/signalr/overview/performance/scaleout-with-sql-server.md +++ b/aspnet/signalr/overview/performance/scaleout-with-sql-server.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/performance/scaleout-with-sql-server title: "SignalR Scaleout with SQL Server | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "Software versions used in this topic Visual Studio 2013 .NET 4.5 SignalR version 2 Previous versions of this topic For information about earlier versions of..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: 98358b6e-9139-4239-ba3a-2d7dd74dd664 msc.legacyurl: /signalr/overview/performance/scaleout-with-sql-server diff --git a/aspnet/signalr/overview/performance/scaleout-with-windows-azure-service-bus.md b/aspnet/signalr/overview/performance/scaleout-with-windows-azure-service-bus.md index 79347521faaa..b1f85b848091 100644 --- a/aspnet/signalr/overview/performance/scaleout-with-windows-azure-service-bus.md +++ b/aspnet/signalr/overview/performance/scaleout-with-windows-azure-service-bus.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/performance/scaleout-with-windows-azure-service-bus title: "SignalR Scaleout with Azure Service Bus | Microsoft Docs" -author: MikeWasson +author: bradygaster description: "Software versions used in this topic Visual Studio 2013 .NET 4.5 SignalR version 2 Previous versions of this topic For the SignalR 1.x version of this topic,..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: ce1305f9-30fd-49e3-bf38-d0a78dfb06c3 msc.legacyurl: /signalr/overview/performance/scaleout-with-windows-azure-service-bus diff --git a/aspnet/signalr/overview/performance/signalr-connection-density-testing-with-crank.md b/aspnet/signalr/overview/performance/signalr-connection-density-testing-with-crank.md index 3e7de638681d..b7655f423bd8 100644 --- a/aspnet/signalr/overview/performance/signalr-connection-density-testing-with-crank.md +++ b/aspnet/signalr/overview/performance/signalr-connection-density-testing-with-crank.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/performance/signalr-connection-density-testing-with-crank title: "SignalR Connection Density Testing with Crank | Microsoft Docs" -author: Rick-Anderson +author: bradygaster description: "SignalR Connection Density Testing with Crank" -ms.author: riande +ms.author: bradyg ms.date: 02/22/2015 ms.assetid: 148d9ca7-1af1-44b6-a9fb-91e261b9b463 msc.legacyurl: /signalr/overview/performance/signalr-connection-density-testing-with-crank diff --git a/aspnet/signalr/overview/performance/signalr-performance.md b/aspnet/signalr/overview/performance/signalr-performance.md index 3c73d713ba6a..110c2a137656 100644 --- a/aspnet/signalr/overview/performance/signalr-performance.md +++ b/aspnet/signalr/overview/performance/signalr-performance.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/performance/signalr-performance title: "SignalR Performance | Microsoft Docs" -author: pfletcher +author: bradygaster description: "SignalR Performance" -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: 3751f5e7-59db-4be0-a290-50abc24e5c84 msc.legacyurl: /signalr/overview/performance/signalr-performance diff --git a/aspnet/signalr/overview/performance/using-signalr-performance-counters-in-an-azure-web-role.md b/aspnet/signalr/overview/performance/using-signalr-performance-counters-in-an-azure-web-role.md index 5a9aeb51447d..9048e043a921 100644 --- a/aspnet/signalr/overview/performance/using-signalr-performance-counters-in-an-azure-web-role.md +++ b/aspnet/signalr/overview/performance/using-signalr-performance-counters-in-an-azure-web-role.md @@ -4,7 +4,7 @@ title: Using SignalR performance counters in an Azure Web Role | Microsoft Docs author: guardrex description: How to install and use SignalR performance counters in an Azure Web Role. keywords: ASP.NET,signalr,performance counter,azure web role -ms.author: riande +ms.author: bradyg ms.date: 10/03/2018 ms.assetid: 2a127d3b-21ed-4cc9-bec0-cdab4e742a25 msc.legacyurl: /signalr/overview/performance/using-signalr-performance-counters-in-an-azure-web-role diff --git a/aspnet/signalr/overview/releases/index.md b/aspnet/signalr/overview/releases/index.md index b8083332464e..3e20ba817245 100644 --- a/aspnet/signalr/overview/releases/index.md +++ b/aspnet/signalr/overview/releases/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/releases/index title: "SignalR Releases | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "Information about SignalR releases and how to upgrade from earlier to later releases." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: 0d951e85-b83b-4e53-9f1e-eb1ca1fc72c5 msc.legacyurl: /signalr/overview/releases diff --git a/aspnet/signalr/overview/releases/upgrading-signalr-1x-projects-to-20.md b/aspnet/signalr/overview/releases/upgrading-signalr-1x-projects-to-20.md index 0228ee528c17..454c35ad9e7b 100644 --- a/aspnet/signalr/overview/releases/upgrading-signalr-1x-projects-to-20.md +++ b/aspnet/signalr/overview/releases/upgrading-signalr-1x-projects-to-20.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/releases/upgrading-signalr-1x-projects-to-20 title: "Upgrading SignalR 1.x Projects to version 2 | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic describes how to upgrade an existing SignalR 1.x project to SignalR 2.x, and how to troubleshoot issues that may arise during the upgrade process...." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: adcfef99-9bc5-489d-a91b-9b7c2bc35e04 msc.legacyurl: /signalr/overview/releases/upgrading-signalr-1x-projects-to-20 diff --git a/aspnet/signalr/overview/security/hub-authorization.md b/aspnet/signalr/overview/security/hub-authorization.md index 8074bcba9160..c597e7fc1640 100644 --- a/aspnet/signalr/overview/security/hub-authorization.md +++ b/aspnet/signalr/overview/security/hub-authorization.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/security/hub-authorization title: "Authentication and Authorization for SignalR Hubs | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic describes how to restrict which users or roles can access hub methods. Software versions used in this topic Visual Studio 2013 .NET 4.5 SignalR ve..." -ms.author: riande +ms.author: bradyg ms.date: 01/05/2015 ms.assetid: a610c796-c131-473c-baef-2e6c568cb2a2 msc.legacyurl: /signalr/overview/security/hub-authorization diff --git a/aspnet/signalr/overview/security/index.md b/aspnet/signalr/overview/security/index.md index 0b9fc2da2e9c..5fd2a222df66 100644 --- a/aspnet/signalr/overview/security/index.md +++ b/aspnet/signalr/overview/security/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/security/index title: "SignalR Security | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "Understanding and handling security issues in SignalR applications." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: 8faa734d-ab55-4b09-be54-564595d2ec78 msc.legacyurl: /signalr/overview/security diff --git a/aspnet/signalr/overview/security/introduction-to-security.md b/aspnet/signalr/overview/security/introduction-to-security.md index 567a0dc92984..022a28bf2a06 100644 --- a/aspnet/signalr/overview/security/introduction-to-security.md +++ b/aspnet/signalr/overview/security/introduction-to-security.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/security/introduction-to-security title: "Introduction to SignalR Security | Microsoft Docs" -author: pfletcher +author: bradygaster description: "Describes the security issues you must consider when developing a SignalR application." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: ed562717-8591-4936-8e10-c7e63dcb570a msc.legacyurl: /signalr/overview/security/introduction-to-security diff --git a/aspnet/signalr/overview/security/persistent-connection-authorization.md b/aspnet/signalr/overview/security/persistent-connection-authorization.md index 48a49a430a55..bbd006407dae 100644 --- a/aspnet/signalr/overview/security/persistent-connection-authorization.md +++ b/aspnet/signalr/overview/security/persistent-connection-authorization.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/security/persistent-connection-authorization title: "Authentication and Authorization for SignalR Persistent Connections | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This topic describes how to enforce authorization on a persistent connection. For general information about integrating security into a SignalR application,..." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: e264677b-9c01-47ec-94f9-3cd8f08f94af msc.legacyurl: /signalr/overview/security/persistent-connection-authorization diff --git a/aspnet/signalr/overview/testing-and-debugging/enabling-signalr-tracing.md b/aspnet/signalr/overview/testing-and-debugging/enabling-signalr-tracing.md index f3070396e369..a4a4d419091b 100644 --- a/aspnet/signalr/overview/testing-and-debugging/enabling-signalr-tracing.md +++ b/aspnet/signalr/overview/testing-and-debugging/enabling-signalr-tracing.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/testing-and-debugging/enabling-signalr-tracing title: "Enabling SignalR Tracing | Microsoft Docs" -author: Rick-Anderson +author: bradygaster description: "This document describes how to enable and configure tracing for SignalR servers and clients. Tracing enables you to view diagnostic information about events..." -ms.author: riande +ms.author: bradyg ms.date: 08/08/2014 ms.assetid: 30060acb-be3e-4347-996f-3870f0c37829 msc.legacyurl: /signalr/overview/testing-and-debugging/enabling-signalr-tracing diff --git a/aspnet/signalr/overview/testing-and-debugging/index.md b/aspnet/signalr/overview/testing-and-debugging/index.md index 9d83af7e27e6..629cb1b9ef30 100644 --- a/aspnet/signalr/overview/testing-and-debugging/index.md +++ b/aspnet/signalr/overview/testing-and-debugging/index.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/testing-and-debugging/index title: "SignalR Testing and Debugging | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "How to test and debug SignalR applications." -ms.author: riande +ms.author: bradyg ms.date: 09/19/2014 ms.assetid: 437f6dec-ab4b-4d12-af71-e8ab028aab7b msc.legacyurl: /signalr/overview/testing-and-debugging diff --git a/aspnet/signalr/overview/testing-and-debugging/troubleshooting.md b/aspnet/signalr/overview/testing-and-debugging/troubleshooting.md index 0ccb91cbf143..1222530396f5 100644 --- a/aspnet/signalr/overview/testing-and-debugging/troubleshooting.md +++ b/aspnet/signalr/overview/testing-and-debugging/troubleshooting.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/testing-and-debugging/troubleshooting title: "SignalR Troubleshooting | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This article describes common issues with developing SignalR applications." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: 4b559e6c-4fb0-4a04-9812-45cf08ae5779 msc.legacyurl: /signalr/overview/testing-and-debugging/troubleshooting diff --git a/aspnet/signalr/overview/testing-and-debugging/unit-testing-signalr-applications.md b/aspnet/signalr/overview/testing-and-debugging/unit-testing-signalr-applications.md index 394120c21f51..555c83b866ba 100644 --- a/aspnet/signalr/overview/testing-and-debugging/unit-testing-signalr-applications.md +++ b/aspnet/signalr/overview/testing-and-debugging/unit-testing-signalr-applications.md @@ -1,9 +1,9 @@ --- uid: signalr/overview/testing-and-debugging/unit-testing-signalr-applications title: "Unit Testing SignalR Applications | Microsoft Docs" -author: pfletcher +author: bradygaster description: "This article describes how to use the Unit Testing features of SignalR 2.0." -ms.author: riande +ms.author: bradyg ms.date: 06/10/2014 ms.assetid: d1983524-e0d5-4ee6-9d87-1f552f7cb964 msc.legacyurl: /signalr/overview/testing-and-debugging/unit-testing-signalr-applications diff --git a/aspnet/signalr/videos/getting-started/index.md b/aspnet/signalr/videos/getting-started/index.md index 8e1676e04213..b475fce8a0c3 100644 --- a/aspnet/signalr/videos/getting-started/index.md +++ b/aspnet/signalr/videos/getting-started/index.md @@ -1,9 +1,9 @@ --- uid: signalr/videos/getting-started/index title: "ASP.NET SignalR Videos | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "These videos give you background and application examples for using SignalR to add real-time functionality to web applications." -ms.author: riande +ms.author: bradyg ms.date: 12/12/2012 ms.assetid: d8d03cc9-13bc-4921-9aca-3dfbda53660d msc.legacyurl: /signalr/videos/getting-started diff --git a/aspnet/signalr/videos/getting-started/signalr-and-web-sockets.md b/aspnet/signalr/videos/getting-started/signalr-and-web-sockets.md index cb1c6fc7fe9a..f3f0a466a22e 100644 --- a/aspnet/signalr/videos/getting-started/signalr-and-web-sockets.md +++ b/aspnet/signalr/videos/getting-started/signalr-and-web-sockets.md @@ -3,7 +3,7 @@ uid: signalr/videos/getting-started/signalr-and-web-sockets title: "SignalR and Web Sockets | Microsoft Docs" author: shanselman description: "Scott Hanselman introduces SignalR and Web Sockets." -ms.author: riande +ms.author: bradyg ms.date: 08/15/2012 ms.assetid: d20b4bfc-2cc1-4aeb-b235-733146df1eca msc.legacyurl: /signalr/videos/getting-started/signalr-and-web-sockets diff --git a/aspnet/signalr/videos/index.md b/aspnet/signalr/videos/index.md index f4807963b674..543bece601b5 100644 --- a/aspnet/signalr/videos/index.md +++ b/aspnet/signalr/videos/index.md @@ -1,9 +1,9 @@ --- uid: signalr/videos/index title: "ASP.NET SignalR Videos | Microsoft Docs" -author: rick-anderson +author: bradygaster description: "" -ms.author: riande +ms.author: bradyg ms.date: 12/12/2012 ms.assetid: c0ea52a3-7497-4204-88c6-91591ac1a6b2 msc.legacyurl: /signalr/videos diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1.md b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1.md index ed80a3af3327..b133c77d4c1f 100644 --- a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1.md +++ b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1.md @@ -4,25 +4,24 @@ title: "Using Web API 2 with Entity Framework 6 | Microsoft Docs" author: MikeWasson description: "This tutorial will teach you the basics of creating a web application with an ASP.NET Web API back end. The tutorial uses Entity Framework 6 for the data lay..." ms.author: riande -ms.date: 05/28/2015 +ms.date: 01/17/2019 ms.assetid: e879487e-dbcd-4b33-b092-d67c37ae768c msc.legacyurl: /web-api/overview/data/using-web-api-with-entity-framework/part-1 msc.type: authoredcontent --- Using Web API 2 with Entity Framework 6 ==================== -by [Mike Wasson](https://github.com/MikeWasson) [Download Completed Project](https://github.com/MikeWasson/BookService) -> This tutorial will teach you the basics of creating a web application with an ASP.NET Web API back end. The tutorial uses Entity Framework 6 for the data layer, and Knockout.js for the client-side JavaScript application. The tutorial also shows how to deploy the app to Azure App Service Web Apps. +> This tutorial teaches you the basics of creating a web application with an ASP.NET Web API back end. The tutorial uses Entity Framework 6 for the data layer, and Knockout.js for the client-side JavaScript application. The tutorial also shows how to deploy the app to Azure App Service Web Apps. > > ## Software versions used in the tutorial > > - Web API 2.1 -> - Visual Studio 2013 (download Visual Studio 2017 [here](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=button+cta&utm_content=download+vs2017)) +> - Visual Studio 2017 (download Visual Studio 2017 [here](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=button+cta&utm_content=download+vs2017)) > - Entity Framework 6 -> - .NET 4.5 +> - .NET 4.7 > - [Knockout.js](http://knockoutjs.com/) 3.1 This tutorial uses ASP.NET Web API 2 with Entity Framework 6 to create a web application that manipulates a back-end database. Here is a screen shot of the application that you will create. @@ -40,9 +39,9 @@ Here are the main building blocks for this app: - Knockout.js data-binds the HTML elements to the JSON data. - Entity Framework talks to the database. -## See this App Running on Azure +## See this app running on Azure -Would you like to see the finished site running as a live web app? You can deploy a complete version of the app to your Azure account by simply clicking the following button. +Would you like to see the finished site running as a live web app? You can deploy a complete version of the app to your Azure account by selecting the following button. [![](http://azuredeploy.net/deploybutton.png)](https://azuredeploy.net/?WT.mc_id=deploy_azure_aspnet&repository=https://github.com/tfitzmac/BookService) @@ -51,31 +50,49 @@ You need an Azure account to deploy this solution to Azure. If you do not alread - [Open an Azure account for free](https://azure.microsoft.com/pricing/free-trial/?WT.mc_id=A443DD604) - You get credits you can use to try out paid Azure services, and even after they're used up you can keep the account and use free Azure services. - [Activate MSDN subscriber benefits](https://azure.microsoft.com/pricing/member-offers/msdn-benefits-details/?WT.mc_id=A443DD604) - Your MSDN subscription gives you credits every month that you can use for paid Azure services. -## Create the Project +## Create the project -Open Visual Studio. From the **File** menu, select **New**, then select **Project**. (Or click **New Project** on the Start page.) +Open Visual Studio. From the **File** menu, select **New**, then select **Project**. (Or select **New Project** on the Start page.) -In the **New Project** dialog, click **Web** in the left pane and **ASP.NET Web Application** in the middle pane. Name the project BookService and click **OK**. +In the **New Project** dialog, select **Web** in the left pane and **ASP.NET Web Application (.NET Framework)** in the middle pane. Name the project **BookService** and select **OK**. -[![](part-1/_static/image4.png)](part-1/_static/image3.png) +[![](part-1/_static/image11.png)](part-1/_static/image11.png) In the **New ASP.NET Project** dialog, select the **Web API** template. -[![](part-1/_static/image6.png)](part-1/_static/image5.png) +[![](part-1/_static/image12.png)](part-1/_static/image12.png) -If you want to host the project in a Azure App Service, leave the **Host in the cloud** box checked. -Click **OK** to create the project. +Select **OK** to create the project. -## Configure Azure Settings (Optional) +## Configure Azure settings (optional) -If you left the **Host in Cloud** option checked, Visual Studio will prompt you to sign in to Microsoft Azure +After you create the project, you can choose to deploy to Azure App Service Web Apps at any time. -[![](part-1/_static/image8.png)](part-1/_static/image7.png) +1. In Solution Explorer, right-click on your project and select **Publish**. -After you sign in to Azure, Visual Studio prompts you to configure the web app. Enter a name for the site, select your Azure subscription, and select a geographical region. Under **Database server**, select **Create new server**. Enter an administrator username and password. +2. In the window that appears, select **Start**. The **Pick a publish target** dialog box appears. + + [![](part-1/_static/image14.png)](part-1/_static/image14.png) + +3. Select **Create Profile**. The **Create App Service** dialog box appears. + + [![](part-1/_static/image15.png)](part-1/_static/image15.png) + + Accept the defaults, or enter different values for the application name, resource group, hosting plan, Azure subscription, and geographical region. + +4. Select **Create a SQL database**. The **Configure SQL Server** dialog box appears. + + [![](part-1/_static/image16.png)](part-1/_static/image16.png) + + Accept the defaults or enter different values. Enter an **Adminstrator Username** and **Administrator Password** for your new database. Select **OK** when you're done. The **Create App Service** page reappears. + +5. Select **Create** to create your profile. A message appears in the lower-right corner indicating that deployment is in progress. After a short while, the **Publish** window reappears. + + [![](part-1/_static/image17.png)](part-1/_static/image17.png) + + The profile you created to deploy the app is now available. -[![](part-1/_static/image10.png)](part-1/_static/image9.png) > [!div class="step-by-step"] > [Next](part-2.md) diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image11.png b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image11.png new file mode 100644 index 000000000000..9844de3e02aa Binary files /dev/null and b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image11.png differ diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image12.png b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image12.png new file mode 100644 index 000000000000..260ce53af8fc Binary files /dev/null and b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image12.png differ diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image13.png b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image13.png new file mode 100644 index 000000000000..fea3ca4fc2c3 Binary files /dev/null and b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image13.png differ diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image14.png b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image14.png new file mode 100644 index 000000000000..21dd6de3f11b Binary files /dev/null and b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image14.png differ diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image15.png b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image15.png new file mode 100644 index 000000000000..9813b0181047 Binary files /dev/null and b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image15.png differ diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image16.png b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image16.png new file mode 100644 index 000000000000..a4e68c94a785 Binary files /dev/null and b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image16.png differ diff --git a/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image17.png b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image17.png new file mode 100644 index 000000000000..89de282ecaca Binary files /dev/null and b/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-1/_static/image17.png differ diff --git a/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api.md b/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api.md index b61483629036..1801cf16e050 100644 --- a/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api.md +++ b/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api.md @@ -172,7 +172,7 @@ If you click the Response body tab, you can see how the product list was seriali Would you like to see the finished site running as a live web app? You can deploy a complete version of the app to your Azure account by simply clicking the following button. -[![](http://azuredeploy.net/deploybutton.png)](https://deploy.azure.com/?WT.mc_id=deploy_azure_aspnet&repository=https://github.com/tfitzmac/WebAPI-ProductsApp#/form/setup) +[![](https://azuredeploy.net/deploybutton.png)](https://deploy.azure.com/?WT.mc_id=deploy_azure_aspnet&repository=https://github.com/tfitzmac/WebAPI-ProductsApp#/form/setup) You need an Azure account to deploy this solution to Azure. If you do not already have an account, you have the following options: diff --git a/aspnet/whitepapers/aspnet-web-deployment-content-map.md b/aspnet/whitepapers/aspnet-web-deployment-content-map.md index 25c25e6d3466..4eb6255aa393 100644 --- a/aspnet/whitepapers/aspnet-web-deployment-content-map.md +++ b/aspnet/whitepapers/aspnet-web-deployment-content-map.md @@ -13,7 +13,7 @@ ASP.NET Web Deployment - Recommended Resources ==================== > This topic provides links to documentation resources about how to deploy (publish) ASP.NET web applications to IIS by using Visual Studio 2010, Visual Web Developer 2010, and later versions. > -> If you know a great blog post, [stackoverflow](http://stackoverflow.com) thread, or any other link that would be useful, [send us an email](mailto:aspnetue@microsoft.com?subject=Deployment Content Map) with the link. +> If you know a great blog post, [stackoverflow](http://stackoverflow.com) thread, or any other link that would be useful, [send us an email](mailto:aspnetue@microsoft.com?subject=Deployment%20Content%20Map) with the link. > > > [!NOTE] > > diff --git a/aspnetcore/data/ef-rp/sort-filter-page.md b/aspnetcore/data/ef-rp/sort-filter-page.md index 97c6abd8773e..d9f9cbf71ba5 100644 --- a/aspnetcore/data/ef-rp/sort-filter-page.md +++ b/aspnetcore/data/ef-rp/sort-filter-page.md @@ -254,6 +254,8 @@ In the *SchoolViewModels* folder, add a *EnrollmentDateGroup.cs* with the follow ### Update the About page model +The web templates in ASP.NET Core 2.2 do not include the About page. If you are using ASP.NET Core 2.2, create the About Razor Page. + Update the *Pages/About.cshtml.cs* file with the following code: [!code-csharp[](intro/samples/cu21/Pages/About.cshtml.cs)] diff --git a/aspnetcore/docfx.json b/aspnetcore/docfx.json index 955a7bbb7e3f..20cc785ab633 100644 --- a/aspnetcore/docfx.json +++ b/aspnetcore/docfx.json @@ -3,7 +3,8 @@ "content": [ { "files": [ - "**/*.md" + "**/*.md", + "**/*.yml" ], "exclude": [ "**/obj/**", diff --git a/aspnetcore/fundamentals/app-state.md b/aspnetcore/fundamentals/app-state.md index 2aa5a0d9671c..c9856e2048ff 100644 --- a/aspnetcore/fundamentals/app-state.md +++ b/aspnetcore/fundamentals/app-state.md @@ -42,7 +42,7 @@ Be mindful of the [European Union General Data Protection Regulations (GDPR)](ht ## Session state -Session state is an ASP.NET Core scenario for storage of user data while the user browses a web app. Session state uses a store maintained by the app to persist data across requests from a client. The session data is backed by a cache and considered ephemeral data—the site should continue to function without the session data. +Session state is an ASP.NET Core scenario for storage of user data while the user browses a web app. Session state uses a store maintained by the app to persist data across requests from a client. The session data is backed by a cache and considered ephemeral data—the site should continue to function without the session data. Critical application data should be stored in the user database and cached in session only as a performance optimization. > [!NOTE] > Session isn't supported in [SignalR](xref:signalr/index) apps because a [SignalR Hub](xref:signalr/hubs) may execute independent of an HTTP context. For example, this can occur when a long polling request is held open by a hub beyond the lifetime of the request's HTTP context. diff --git a/aspnetcore/fundamentals/configuration/index.md b/aspnetcore/fundamentals/configuration/index.md index ecf82024e893..5209220a9d95 100644 --- a/aspnetcore/fundamentals/configuration/index.md +++ b/aspnetcore/fundamentals/configuration/index.md @@ -4,7 +4,7 @@ author: guardrex description: Learn how to use the Configuration API to configure an ASP.NET Core app. ms.author: riande ms.custom: mvc -ms.date: 12/07/2018 +ms.date: 01/25/2019 uid: fundamentals/configuration/index --- # Configuration in ASP.NET Core @@ -50,12 +50,6 @@ The *options pattern* is an extension of the configuration concepts described in [View or download sample code](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/configuration/index/samples) ([how to download](xref:index#how-to-download-a-sample)) -The examples provided in this topic rely upon: - -* Setting the base path of the app with . `SetBasePath` is made available to an app by referencing the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package. -* Resolving sections of configuration files with . `GetSection` is made available to an app by referencing the [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) package. -* Binding configuration to .NET classes with and [Get<T>](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Get*). `Bind` and `Get` are made available to an app by referencing the [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) package. `Get` is available in ASP.NET Core 1.1 or later. - ::: moniker range=">= aspnetcore-2.1" These three packages are included in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). @@ -72,6 +66,22 @@ These three packages are included in the [Microsoft.AspNetCore.All metapackage]( Before the app is configured and started, a *host* is configured and launched. The host is responsible for app startup and lifetime management. Both the app and the host are configured using the configuration providers described in this topic. Host configuration key-value pairs become part of the app's global configuration. For more information on how the configuration providers are used when the host is built and how configuration sources affect host configuration, see . +## Default configuration + +Web apps based on the ASP.NET Core [dotnet new](/dotnet/core/tools/dotnet-new) templates call when building a host. `CreateDefaultBuilder` provides default configuration for the app. + +* Host configuration is provided from: + * Environment variables prefixed with `ASPNETCORE_` (for example, `ASPNETCORE_ENVIRONMENT`) using the [Environment Variables Configuration Provider](#environment-variables-configuration-provider). + * Command-line arguments using the [Command-line Configuration Provider](#command-line-configuration-provider). +* App configuration is provided from (in the following order): + * *appsettings.json* using the [File Configuration Provider](#file-configuration-provider). + * *appsettings.{Environment}.json* using the [File Configuration Provider](#file-configuration-provider). + * [Secret Manager](xref:security/app-secrets) when the app runs in the `Development` environment using the entry assembly. + * Environment variables using the [Environment Variables Configuration Provider](#environment-variables-configuration-provider). + * Command-line arguments using the [Command-line Configuration Provider](#command-line-configuration-provider). + +The configuration providers are explained later in this topic. For more information on the host and `CreateDefaultBuilder`, see . + ## Security Adopt the following best practices: @@ -110,7 +120,7 @@ When the file is read into configuration, unique keys are created to maintain th * section1:key0 * section1:key1 - and methods are available to isolate sections and children of a section in the configuration data. These methods are described later in [GetSection, GetChildren, and Exists](#getsection-getchildren-and-exists). + and methods are available to isolate sections and children of a section in the configuration data. These methods are described later in [GetSection, GetChildren, and Exists](#getsection-getchildren-and-exists). `GetSection` is in the [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). ## Conventions @@ -232,7 +242,8 @@ public void ConfigureServices(IServiceCollection services) } ``` -In the preceding example, the environment name (`env.EnvironmentName`) and app assembly name (`env.ApplicationName`) are provided by the . For more information, see . +In the preceding example, the environment name (`env.EnvironmentName`) and app assembly name (`env.ApplicationName`) are provided by the . For more information, see . The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). +. ::: moniker-end @@ -240,7 +251,7 @@ In the preceding example, the environment name (`env.EnvironmentName`) and app a ## ConfigureAppConfiguration -Call when building the Web Host to specify the app's configuration providers in addition to those added automatically by : +Call when building the host to specify the app's configuration providers in addition to those added automatically by : [!code-csharp[](index/samples/2.x/ConfigurationSample/Program.cs?name=snippet_Program&highlight=19)] @@ -757,6 +768,8 @@ public class Program } ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + When creating a directly, call with the configuration: ::: moniker-end @@ -787,6 +800,8 @@ public class Program } ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + When creating a directly, call with the configuration: ::: moniker-end @@ -809,6 +824,8 @@ var host = new WebHostBuilder() .UseStartup(); ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + A generic example of an INI configuration file: ```ini @@ -888,6 +905,8 @@ public class Program } ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + When creating a directly, call with the configuration: ::: moniker-end @@ -920,6 +939,8 @@ public class Program } ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + When creating a directly, call with the configuration: ::: moniker-end @@ -942,6 +963,8 @@ var host = new WebHostBuilder() .UseStartup(); ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + **Example** ::: moniker range=">= aspnetcore-2.0" @@ -1003,6 +1026,8 @@ public class Program } ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + When creating a directly, call with the configuration: ::: moniker-end @@ -1033,6 +1058,8 @@ public class Program } ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + When creating a directly, call with the configuration: ::: moniker-end @@ -1055,6 +1082,8 @@ var host = new WebHostBuilder() .UseStartup(); ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + XML configuration files can use distinct element names for repeating sections: ```xml @@ -1155,6 +1184,8 @@ public class Program } ``` +The base path is set with . `SetBasePath` is in the [Microsoft.Extensions.Configuration.FileExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.FileExtensions/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + When creating a directly, call with the configuration: ```csharp @@ -1320,7 +1351,7 @@ When the file is read into configuration, the following unique hierarchical keys ### GetSection -[IConfiguration.GetSection](xref:Microsoft.Extensions.Configuration.IConfiguration.GetSection*) extracts a configuration subsection with the specified subsection key. +[IConfiguration.GetSection](xref:Microsoft.Extensions.Configuration.IConfiguration.GetSection*) extracts a configuration subsection with the specified subsection key. `GetSection` is in the [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). To return an containing only the key-value pairs in `section1`, call `GetSection` and supply the section name: @@ -1328,6 +1359,8 @@ To return an con var configSection = _config.GetSection("section1"); ``` +The `configSection` doesn't have a value, only a key and a path. + Similarly, to obtain the values for keys in `section2:subsection0`, call `GetSection` and supply the section path: ```csharp @@ -1336,6 +1369,8 @@ var configSection = _config.GetSection("section2:subsection0"); `GetSection` never returns `null`. If a matching section isn't found, an empty `IConfigurationSection` is returned. +When `GetSection` returns a matching section, isn't populated. A and are returned when the section exists. + ### GetChildren A call to [IConfiguration.GetChildren](xref:Microsoft.Extensions.Configuration.IConfiguration.GetChildren*) on `section2` obtains an `IEnumerable` that includes: @@ -1367,7 +1402,7 @@ Given the example data, `sectionExists` is `false` because there isn't a `sectio Configuration can be bound to classes that represent groups of related settings using the *options pattern*. For more information, see . -Configuration values are returned as strings, but calling enables the construction of [POCO](https://wikipedia.org/wiki/Plain_Old_CLR_Object) objects. +Configuration values are returned as strings, but calling enables the construction of [POCO](https://wikipedia.org/wiki/Plain_Old_CLR_Object) objects. `Bind` is in the [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). The sample app contains a `Starship` model (*Models/Starship.cs*): @@ -1422,9 +1457,11 @@ The sample app calls `GetSection` with the `starship` key. The `starship` key-va ::: moniker-end +`GetSection` is in the [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + ## Bind to an object graph - is capable of binding an entire POCO object graph. + is capable of binding an entire POCO object graph. `Bind` is in the [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). The sample contains a `TvShow` model whose object graph includes `Metadata` and `Actors` classes (*Models/TvShow.cs*): @@ -1494,11 +1531,13 @@ viewModel.TvShow = tvShow; ::: moniker-end + is in the [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). `Get` is available in ASP.NET Core 1.1 or later. `GetSection` is in the [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + ## Bind an array to a class *The sample app demonstrates the concepts explained in this section.* -The supports binding arrays to objects using array indices in configuration keys. Any array format that exposes a numeric key segment (`:0:`, `:1:`, … `:{n}:`) is capable of array binding to a POCO class array. +The supports binding arrays to objects using array indices in configuration keys. Any array format that exposes a numeric key segment (`:0:`, `:1:`, … `:{n}:`) is capable of array binding to a POCO class array. `Bind`` is in the [Microsoft.Extensions.Configuration.Binder](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). > [!NOTE] > Binding is provided by convention. Custom configuration providers aren't required to implement array binding. @@ -1552,6 +1591,8 @@ var arrayExample = new ArrayExample(); _config.GetSection("array").Bind(arrayExample); ``` +`GetSection` is in the [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration/) package, which is in the [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app). + ::: moniker range=">= aspnetcore-1.1" [ConfigurationBinder.Get<T>](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Get*) syntax can also be used, which results in more compact code: diff --git a/aspnetcore/fundamentals/environments.md b/aspnetcore/fundamentals/environments.md index eebc8456df1d..5562a85b974f 100644 --- a/aspnetcore/fundamentals/environments.md +++ b/aspnetcore/fundamentals/environments.md @@ -3,7 +3,7 @@ title: Use multiple environments in ASP.NET Core author: rick-anderson description: Learn how to control app behavior across multiple environments in ASP.NET Core apps. ms.author: riande -ms.date: 07/03/2018 +ms.date: 01/22/2019 uid: fundamentals/environments --- # Use multiple environments in ASP.NET Core @@ -232,6 +232,20 @@ When the `ASPNETCORE_ENVIRONMENT` environment variable is set globally, it takes To set the `ASPNETCORE_ENVIRONMENT` environment variable with *web.config*, see the *Setting environment variables* section of . When the `ASPNETCORE_ENVIRONMENT` environment variable is set with *web.config*, its value overrides a setting at the system level. +::: moniker range=">= aspnetcore-2.2" + +**Project file or publish profile** + +**For Windows IIS deployments:** Include the `` property in the publish profile (*.pubxml*) or project file. This approach sets the environment in *web.config* when the project is published: + +```xml + + Development + +``` + +::: moniker-end + **Per IIS Application Pool** To set the `ASPNETCORE_ENVIRONMENT` environment variable for an app running in an isolated Application Pool (supported on IIS 10.0 or later), see the *AppCmd.exe command* section of the [Environment Variables <environmentVariables>](/iis/configuration/system.applicationHost/applicationPools/add/environmentVariables/#appcmdexe) topic. When the `ASPNETCORE_ENVIRONMENT` environment variable is set for an app pool, its value overrides a setting at the system level. diff --git a/aspnetcore/fundamentals/host/hosted-services/samples/2.x/BackgroundTasksSample-GenericHost/Program.cs b/aspnetcore/fundamentals/host/hosted-services/samples/2.x/BackgroundTasksSample-GenericHost/Program.cs index bd673a6606c1..b840bc4ba426 100644 --- a/aspnetcore/fundamentals/host/hosted-services/samples/2.x/BackgroundTasksSample-GenericHost/Program.cs +++ b/aspnetcore/fundamentals/host/hosted-services/samples/2.x/BackgroundTasksSample-GenericHost/Program.cs @@ -18,9 +18,12 @@ public static async Task Main(string[] args) config.AddConsole(); config.AddDebug(); }) - .ConfigureAppConfiguration((hostContext, config) => + .ConfigureHostConfiguration(config => { config.AddEnvironmentVariables(); + }) + .ConfigureAppConfiguration((hostContext, config) => + { config.AddJsonFile("appsettings.json", optional: true); config.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: true); config.AddCommandLine(args); diff --git a/aspnetcore/fundamentals/http-requests.md b/aspnetcore/fundamentals/http-requests.md index a2870b0972bb..2ff2b75776bb 100644 --- a/aspnetcore/fundamentals/http-requests.md +++ b/aspnetcore/fundamentals/http-requests.md @@ -5,14 +5,14 @@ description: Learn about using the IHttpClientFactory interface to manage logica monikerRange: '>= aspnetcore-2.1' ms.author: scaddie ms.custom: mvc -ms.date: 08/07/2018 +ms.date: 01/25/2019 uid: fundamentals/http-requests --- # Initiate HTTP requests By [Glenn Condron](https://github.com/glennc), [Ryan Nowak](https://github.com/rynowak), and [Steve Gordon](https://github.com/stevejgordon) -An [IHttpClientFactory](/dotnet/api/system.net.http.ihttpclientfactory) can be registered and used to configure and create [HttpClient](/dotnet/api/system.net.http.httpclient) instances in an app. It offers the following benefits: +An can be registered and used to configure and create instances in an app. It offers the following benefits: * Provides a central location for naming and configuring logical `HttpClient` instances. For example, a *github* client can be registered and configured to access GitHub. A default client can be registered for other purposes. * Codifies the concept of outgoing middleware via delegating handlers in `HttpClient` and provides extensions for Polly-based middleware to take advantage of that. @@ -42,11 +42,11 @@ The `IHttpClientFactory` can be registered by calling the `AddHttpClient` extens [!code-csharp[](http-requests/samples/2.x/HttpClientFactorySample/Startup.cs?name=snippet1)] -Once registered, code can accept an `IHttpClientFactory` anywhere services can be injected with [dependency injection](xref:fundamentals/dependency-injection) (DI). The `IHttpClientFactory` can be used to create a `HttpClient` instance: +Once registered, code can accept an `IHttpClientFactory` anywhere services can be injected with [dependency injection (DI)](xref:fundamentals/dependency-injection). The `IHttpClientFactory` can be used to create a `HttpClient` instance: [!code-csharp[](http-requests/samples/2.x/HttpClientFactorySample/Pages/BasicUsage.cshtml.cs?name=snippet1&highlight=9-12,21)] -Using `IHttpClientFactory` in this fashion is a great way to refactor an existing app. It has no impact on the way `HttpClient` is used. In places where `HttpClient` instances are currently created, replace those occurrences with a call to [CreateClient](/dotnet/api/system.net.http.ihttpclientfactory.createclient). +Using `IHttpClientFactory` in this fashion is a good way to refactor an existing app. It has no impact on the way `HttpClient` is used. In places where `HttpClient` instances are currently created, replace those occurrences with a call to . ### Named clients @@ -74,7 +74,7 @@ A typed client accepts a `HttpClient` parameter in its constructor: In the preceding code, the configuration is moved into the typed client. The `HttpClient` object is exposed as a public property. It's possible to define API-specific methods that expose `HttpClient` functionality. The `GetAspNetDocsIssues` method encapsulates the code needed to query for and parse out the latest open issues from a GitHub repository. -To register a typed client, the generic `AddHttpClient` extension method can be used within `Startup.ConfigureServices`, specifying the typed client class: +To register a typed client, the generic extension method can be used within `Startup.ConfigureServices`, specifying the typed client class: [!code-csharp[](http-requests/samples/2.x/HttpClientFactorySample/Startup.cs?name=snippet3)] @@ -151,22 +151,42 @@ public class ValuesController : ControllerBase `HttpClient` already has the concept of delegating handlers that can be linked together for outgoing HTTP requests. The `IHttpClientFactory` makes it easy to define the handlers to apply for each named client. It supports registration and chaining of multiple handlers to build an outgoing request middleware pipeline. Each of these handlers is able to perform work before and after the outgoing request. This pattern is similar to the inbound middleware pipeline in ASP.NET Core. The pattern provides a mechanism to manage cross-cutting concerns around HTTP requests, including caching, error handling, serialization, and logging. -To create a handler, define a class deriving from `DelegatingHandler`. Override the `SendAsync` method to execute code before passing the request to the next handler in the pipeline: +To create a handler, define a class deriving from . Override the `SendAsync` method to execute code before passing the request to the next handler in the pipeline: [!code-csharp[Main](http-requests/samples/2.x/HttpClientFactorySample/Handlers/ValidateHeaderHandler.cs?name=snippet1)] The preceding code defines a basic handler. It checks to see if an `X-API-KEY` header has been included on the request. If the header is missing, it can avoid the HTTP call and return a suitable response. -During registration, one or more handlers can be added to the configuration for a `HttpClient`. This task is accomplished via extension methods on the [IHttpClientBuilder](/dotnet/api/microsoft.extensions.dependencyinjection.ihttpclientbuilder). +During registration, one or more handlers can be added to the configuration for a `HttpClient`. This task is accomplished via extension methods on the . [!code-csharp[](http-requests/samples/2.x/HttpClientFactorySample/Startup.cs?name=snippet5)] -In the preceding code, the `ValidateHeaderHandler` is registered with DI. The handler **must** be registered in DI as transient. Once registered, [AddHttpMessageHandler](/dotnet/api/microsoft.extensions.dependencyinjection.httpclientbuilderextensions.addhttpmessagehandler) can be called, passing in the type for the handler. +::: moniker range=">= aspnetcore-2.2" + +In the preceding code, the `ValidateHeaderHandler` is registered with DI. The `IHttpClientFactory` creates a separate DI scope for each handler. Handlers are free to depend upon services of any scope. Services that handlers depend upon are disposed when the handler is disposed. + +Once registered, can be called, passing in the type for the handler. + +::: moniker-end + +::: moniker range="< aspnetcore-2.2" + +In the preceding code, the `ValidateHeaderHandler` is registered with DI. The handler **must** be registered in DI as a transient service, never scoped. If the handler is registered as a scoped service and any services that the handler depends upon are disposable, the handler's services could be disposed before the handler goes out of scope, which would cause the handler to fail. + +Once registered, can be called, passing in the handler type. + +::: moniker-end Multiple handlers can be registered in the order that they should execute. Each handler wraps the next handler until the final `HttpClientHandler` executes the request: [!code-csharp[](http-requests/samples/2.x/HttpClientFactorySample/Startup.cs?name=snippet6)] +Use one of the following approaches to share per-request state with message handlers: + +* Pass data into the handler using `HttpRequestMessage.Properties`. +* Use `IHttpContextAccessor` to access the current request. +* Create a custom `AsyncLocal` storage object to pass the data. + ## Use Polly-based handlers `IHttpClientFactory` integrates with a popular third-party library called [Polly](https://github.com/App-vNext/Polly). Polly is a comprehensive resilience and transient fault-handling library for .NET. It allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner. @@ -215,15 +235,17 @@ Further information about `IHttpClientFactory` and Polly integrations can be fou ## HttpClient and lifetime management -A new `HttpClient` instance is returned each time `CreateClient` is called on the `IHttpClientFactory`. There's an [HttpMessageHandler](/dotnet/api/system.net.http.httpmessagehandler) per named client. `IHttpClientFactory` pools the `HttpMessageHandler` instances created by the factory to reduce resource consumption. An `HttpMessageHandler` instance may be reused from the pool when creating a new `HttpClient` instance if its lifetime hasn't expired. +A new `HttpClient` instance is returned each time `CreateClient` is called on the `IHttpClientFactory`. There's an per named client. The factory manages the lifetimes of the `HttpMessageHandler` instances. + +`IHttpClientFactory` pools the `HttpMessageHandler` instances created by the factory to reduce resource consumption. An `HttpMessageHandler` instance may be reused from the pool when creating a new `HttpClient` instance if its lifetime hasn't expired. Pooling of handlers is desirable as each handler typically manages its own underlying HTTP connections. Creating more handlers than necessary can result in connection delays. Some handlers also keep connections open indefinitely, which can prevent the handler from reacting to DNS changes. -The default handler lifetime is two minutes. The default value can be overridden on a per named client basis. To override it, call [SetHandlerLifetime](/dotnet/api/microsoft.extensions.dependencyinjection.httpclientbuilderextensions.sethandlerlifetime) on the `IHttpClientBuilder` that is returned when creating the client: +The default handler lifetime is two minutes. The default value can be overridden on a per named client basis. To override it, call on the `IHttpClientBuilder` that is returned when creating the client: [!code-csharp[Main](http-requests/samples/2.x/HttpClientFactorySample/Startup.cs?name=snippet11)] -Disposal of the client isn't required. Disposal cancels outgoing requests and guarantees the given `HttpClient` instance can't be used after calling [Dispose](/dotnet/api/system.idisposable.dispose#System_IDisposable_Dispose). `IHttpClientFactory` tracks and disposes resources used by `HttpClient` instances. The `HttpClient` instances can generally be treated as .NET objects not requiring disposal. +Disposal of the client isn't required. Disposal cancels outgoing requests and guarantees the given `HttpClient` instance can't be used after calling . `IHttpClientFactory` tracks and disposes resources used by `HttpClient` instances. The `HttpClient` instances can generally be treated as .NET objects not requiring disposal. Keeping a single `HttpClient` instance alive for a long duration is a common pattern used before the inception of `IHttpClientFactory`. This pattern becomes unnecessary after migrating to `IHttpClientFactory`. @@ -243,6 +265,6 @@ Including the name of the client in the log category enables log filtering for s It may be necessary to control the configuration of the inner `HttpMessageHandler` used by a client. -An `IHttpClientBuilder` is returned when adding named or typed clients. The [ConfigurePrimaryHttpMessageHandler](/dotnet/api/microsoft.extensions.dependencyinjection.httpclientbuilderextensions.configureprimaryhttpmessagehandler) extension method can be used to define a delegate. The delegate is used to create and configure the primary `HttpMessageHandler` used by that client: +An `IHttpClientBuilder` is returned when adding named or typed clients. The extension method can be used to define a delegate. The delegate is used to create and configure the primary `HttpMessageHandler` used by that client: [!code-csharp[Main](http-requests/samples/2.x/HttpClientFactorySample/Startup.cs?name=snippet12)] diff --git a/aspnetcore/fundamentals/routing.md b/aspnetcore/fundamentals/routing.md index f3c3bfd4e277..bedc8f58e3b2 100644 --- a/aspnetcore/fundamentals/routing.md +++ b/aspnetcore/fundamentals/routing.md @@ -660,6 +660,26 @@ For more information on regular expression syntax, see [.NET Framework Regular E To constrain a parameter to a known set of possible values, use a regular expression. For example, `{action:regex(^(list|get|create)$)}` only matches the `action` route value to `list`, `get`, or `create`. If passed into the constraints dictionary, the string `^(list|get|create)$` is equivalent. Constraints that are passed in the constraints dictionary (not inline within a template) that don't match one of the known constraints are also treated as regular expressions. +## Custom Route Constraints + +In addition to the built-in route constraints, custom route constraints can be created by implementing the interface. The `IRouteConstraint` interface contains a single method, `Match`, which returns `true` if the constraint is satisfied and `false` otherwise. + +To use a custom `IRouteConstraint`, the route constraint type must be registered with the app's `RouteOptions.ConstraintMap` in the app's service container. A is a dictionary that maps route constraint keys to `IRouteConstraint` implementations that validate those constraints. An app's `RouteOptions.ConstraintMap` can be updated in `Startup.ConfigureServices` either as part of a `services.AddRouting` call or by configuring `RouteOptions` directly with `services.Configure`. For example: + +```csharp +services.AddRouting(options => +{ + options.ConstraintMap.Add("customName", typeof(MyCustomConstraint)); +}); +``` + +The constraint can then be applied to routes in the usual manner, using the name specified when registering the constraint type. For example: + +```csharp +[HttpGet("{id:customName}")] +public ActionResult Get(string id) +``` + ::: moniker range=">= aspnetcore-2.2" ## Parameter transformer reference @@ -731,3 +751,9 @@ routes.MapRoute("blog_route", "blog/{*slug}", ``` Link generation only generates a link for this route when the matching values for `controller` and `action` are provided. + +## Complex segments + +Complex segments (for example `[Route("/x{token}y")]`) are processed by matching up literals from right to left in a non-greedy way. See [this code](https://github.com/aspnet/AspNetCore/blob/release/2.2/src/Http/Routing/src/Patterns/RoutePatternMatcher.cs#L293) for a detailed explanation of how complex segments are matched. The [code sample](https://github.com/aspnet/AspNetCore/blob/release/2.2/src/Http/Routing/src/Patterns/RoutePatternMatcher.cs#L293) is not used by ASP.NET Core, but it provides a good explanation of complex segments. + diff --git a/aspnetcore/fundamentals/startup.md b/aspnetcore/fundamentals/startup.md index 78e57b3b641a..98ec453f42a5 100644 --- a/aspnetcore/fundamentals/startup.md +++ b/aspnetcore/fundamentals/startup.md @@ -1,108 +1,117 @@ --- title: App startup in ASP.NET Core -author: ardalis -description: Explains how the Startup class in ASP.NET Core configures services and the app's request pipeline. +author: tdykstra +description: Learn how the Startup class in ASP.NET Core configures services and the app's request pipeline. +monikerRange: '>= aspnetcore-2.1' ms.author: tdykstra ms.custom: mvc -ms.date: 4/13/2018 +ms.date: 01/17/2019 uid: fundamentals/startup --- # App startup in ASP.NET Core -By [Steve Smith](https://ardalis.com), [Tom Dykstra](https://github.com/tdykstra), and [Luke Latham](https://github.com/guardrex) +By [Tom Dykstra](https://github.com/tdykstra), [Luke Latham](https://github.com/guardrex), and [Steve Smith](https://ardalis.com) The `Startup` class configures services and the app's request pipeline. -[View or download sample code](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/startup/sample/) ([how to download](xref:index#how-to-download-a-sample)). - ## The Startup class ASP.NET Core apps use a `Startup` class, which is named `Startup` by convention. The `Startup` class: -* Can optionally include a [ConfigureServices](/dotnet/api/microsoft.aspnetcore.hosting.startupbase.configureservices) method to configure the app's services. -* Must include a [Configure](/dotnet/api/microsoft.aspnetcore.hosting.startupbase.configure) method to create the app's request processing pipeline. +* Optionally includes a method to configure the app's *services*. A service is a reusable component that provides app functionality. Services are configured—also described as *registered*—in `ConfigureServices` and consumed across the app via [dependency injection (DI)](xref:fundamentals/dependency-injection) or . +* Includes a method to create the app's request processing pipeline. `ConfigureServices` and `Configure` are called by the runtime when the app starts: -[!code-csharp[](startup/snapshot_sample/Startup1.cs)] +[!code-csharp[](startup/sample_snapshot/Startup1.cs?highlight=4,10)] -Specify the `Startup` class with the [WebHostBuilderExtensions](/dotnet/api/Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions) [UseStartup<TStartup>](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.usestartup#Microsoft_AspNetCore_Hosting_WebHostBuilderExtensions_UseStartup__1_Microsoft_AspNetCore_Hosting_IWebHostBuilder_) method: +The `Startup` class is specified to the app when the app's [host](xref:fundamentals/host/index) is built. The app's host is built when `Build` is called on the host builder in the `Program` class. The `Startup` class is usually specified by calling the [WebHostBuilderExtensions.UseStartup\](xref:Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.UseStartup*) method on the host builder: -[!code-csharp[](../common/samples/WebApplication1DotNetCore2.0App/Program.cs?name=snippet_Main&highlight=10)] +[!code-csharp[](startup/sample_snapshot/Program3.cs?name=snippet_Program&highlight=10)] -The web host provides some services that are available to the `Startup` class constructor. The app adds additional services via `ConfigureServices`. Both the host and app services are then available in `Configure` and throughout the app. +The host provides services that are available to the `Startup` class constructor. The app adds additional services via `ConfigureServices`. Both the host and app services are then available in `Configure` and throughout the app. A common use of [dependency injection](xref:fundamentals/dependency-injection) into the `Startup` class is to inject: -* [IHostingEnvironment](/dotnet/api/Microsoft.AspNetCore.Hosting.IHostingEnvironment) to configure services by environment. -* [IConfiguration](/dotnet/api/microsoft.extensions.configuration.iconfiguration) to read configuration. -* [ILoggerFactory](/dotnet/api/microsoft.extensions.logging.iloggerfactory) to create a logger in `Startup.ConfigureServices`. +* to configure services by environment. +* to read configuration. +* to create a logger in `Startup.ConfigureServices`. -[!code-csharp[](startup/snapshot_sample/Startup2.cs)] +[!code-csharp[](startup/sample_snapshot/Startup2.cs?highlight=7-8)] An alternative to injecting `IHostingEnvironment` is to use a conventions-based approach. When the app defines separate `Startup` classes for different environments (for example, `StartupDevelopment`), the appropriate `Startup` class is selected at runtime. The class whose name suffix matches the current environment is prioritized. If the app is run in the Development environment and includes both a `Startup` class and a `StartupDevelopment` class, the `StartupDevelopment` class is used. For more information, see [Use multiple environments](xref:fundamentals/environments#environment-based-startup-class-and-methods). -To learn more about `WebHostBuilder`, see the [Hosting](xref:fundamentals/host/index) topic. For information on handling errors during startup, see [Startup exception handling](xref:fundamentals/error-handling#startup-exception-handling). +To learn more about the host, see . For information on handling errors during startup, see [Startup exception handling](xref:fundamentals/error-handling#startup-exception-handling). ## The ConfigureServices method -The [ConfigureServices](/dotnet/api/microsoft.aspnetcore.hosting.startupbase.configureservices) method is: +The method is: -* Optional -* Called by the web host before the `Configure` method to configure the app's services. +* Optional. +* Called by the host before the `Configure` method to configure the app's services. * Where [configuration options](xref:fundamentals/configuration/index) are set by convention. -The typical pattern is to call all the `Add{Service}` methods, and then call all the `services.Configure{Service}` methods. For example, see [Configure Identity services](xref:security/authentication/identity#pw). +The typical pattern is to call all the `Add{Service}` methods and then call all of the `services.Configure{Service}` methods. For example, see [Configure Identity services](xref:security/authentication/identity#pw). -Adding services to the service container makes them available within the app and in the `Configure` method. The services are resolved via [dependency injection](xref:fundamentals/dependency-injection) or from [IApplicationBuilder.ApplicationServices](/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder.applicationservices). +The host may configure some services before `Startup` methods are called. For more information, see . -The web host may configure some services before `Startup` methods are called. Details are available in the [Host in ASP.NET Core](xref:fundamentals/host/index) topic. +For features that require substantial setup, there are `Add{Service}` extension methods on . A typical ASP.NET Core app registers services for Entity Framework, Identity, and MVC: -For features that require substantial setup, there are `Add[Service]` extension methods on [IServiceCollection](/dotnet/api/Microsoft.Extensions.DependencyInjection.IServiceCollection). A typical ASP.NET Core app registers services for Entity Framework, Identity, and MVC: +[!code-csharp[](startup/sample_snapshot/Startup3.cs?highlight=4,7,11)] -[!code-csharp[](../common/samples/WebApplication1/Startup.cs?highlight=4,7,11&start=40&end=55)] +Adding services to the service container makes them available within the app and in the `Configure` method. The services are resolved via [dependency injection](xref:fundamentals/dependency-injection) or from . ## The Configure method -The [Configure](/dotnet/api/microsoft.aspnetcore.hosting.startupbase.configure) method is used to specify how the app responds to HTTP requests. The request pipeline is configured by adding [middleware](xref:fundamentals/middleware/index) components to an [IApplicationBuilder](/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder) instance. `IApplicationBuilder` is available to the `Configure` method, but it isn't registered in the service container. Hosting creates an `IApplicationBuilder` and passes it directly to `Configure`. +The method is used to specify how the app responds to HTTP requests. The request pipeline is configured by adding [middleware](xref:fundamentals/middleware/index) components to an instance. `IApplicationBuilder` is available to the `Configure` method, but it isn't registered in the service container. Hosting creates an `IApplicationBuilder` and passes it directly to `Configure`. + +The [ASP.NET Core templates](/dotnet/core/tools/dotnet-new) configure the pipeline with support for: -The [ASP.NET Core templates](/dotnet/core/tools/dotnet-new) configure the pipeline with support for a developer exception page, [BrowserLink](http://vswebessentials.com/features/browserlink), error pages, static files, and ASP.NET Core MVC: +* [Developer exception page](xref:fundamentals/error-handling#the-developer-exception-page) +* [Exception handler](xref:fundamentals/error-handling#configure-a-custom-exception-handling-page) +* [HTTP Strict Transport Security (HSTS)](xref:security/enforcing-ssl#http-strict-transport-security-protocol-hsts) +* [HTTPS redirection](xref:security/enforcing-ssl) +* [Static files](xref:fundamentals/static-files) +* [General Data Protection Regulation (GDPR)](xref:security/gdpr) +* ASP.NET Core [MVC](xref:mvc/overview) and [Razor Pages](xref:razor-pages/index) -[!code-csharp[](../common/samples/WebApplication1DotNetCore2.0App/Startup.cs?range=28-48&highlight=5,6,10,13,15)] +[!code-csharp[](startup/sample_snapshot/Startup4.cs)] -Each `Use` extension method adds a middleware component to the request pipeline. For instance, the `UseMvc` extension method adds the [Routing Middleware](xref:fundamentals/routing) to the request pipeline and configures [MVC](xref:mvc/overview) as the default handler. +Each `Use` extension method adds one or more middleware components to the request pipeline. For instance, the `UseMvc` extension method adds [Routing Middleware](xref:fundamentals/routing) to the request pipeline and configures [MVC](xref:mvc/overview) as the default handler. Each middleware component in the request pipeline is responsible for invoking the next component in the pipeline or short-circuiting the chain, if appropriate. If short-circuiting doesn't occur along the middleware chain, each middleware has a second chance to process the request before it's sent to the client. -Additional services, such as `IHostingEnvironment` and `ILoggerFactory`, may also be specified in the method signature. When specified, additional services are injected if they're available. +Additional services, such as `IHostingEnvironment` and `ILoggerFactory`, may also be specified in the `Configure` method signature. When specified, additional services are injected if they're available. -For more information on how to use `IApplicationBuilder` and the order of middleware processing, see [Middleware](xref:fundamentals/middleware/index). +For more information on how to use `IApplicationBuilder` and the order of middleware processing, see . ## Convenience methods -[ConfigureServices](/dotnet/api/microsoft.aspnetcore.hosting.iwebhostbuilder.configureservices) and [Configure](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.configure) convenience methods can be used instead of specifying a `Startup` class. Multiple calls to `ConfigureServices` append to one another. Multiple calls to `Configure` use the last method call. +To configure services and the request processing pipeline without using a `Startup` class, call `ConfigureServices` and `Configure` convenience methods on the host builder. Multiple calls to `ConfigureServices` append to one another. If multiple `Configure` method calls exist, the last `Configure` call is used. -[!code-csharp[](startup/snapshot_sample/Program.cs?highlight=18,22)] +[!code-csharp[](startup/sample_snapshot/Program1.cs?highlight=18,22)] ## Extend Startup with startup filters -Use [IStartupFilter](/dotnet/api/microsoft.aspnetcore.hosting.istartupfilter) to configure middleware at the beginning or end of an app's [Configure](#the-configure-method) middleware pipeline. `IStartupFilter` is useful to ensure that a middleware runs before or after middleware added by libraries at the start or end of the app's request processing pipeline. +Use to configure middleware at the beginning or end of an app's [Configure](#the-configure-method) middleware pipeline. `IStartupFilter` is useful to ensure that a middleware runs before or after middleware added by libraries at the start or end of the app's request processing pipeline. -`IStartupFilter` implements a single method, [Configure](/dotnet/api/microsoft.aspnetcore.hosting.istartupfilter.configure), which receives and returns an `Action`. An [IApplicationBuilder](/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder) defines a class to configure an app's request pipeline. For more information, see [Create a middleware pipeline with IApplicationBuilder](xref:fundamentals/middleware/index#create-a-middleware-pipeline-with-iapplicationbuilder). +`IStartupFilter` implements a single method, , which receives and returns an `Action`. An defines a class to configure an app's request pipeline. For more information, see [Create a middleware pipeline with IApplicationBuilder](xref:fundamentals/middleware/index#create-a-middleware-pipeline-with-iapplicationbuilder). Each `IStartupFilter` implements one or more middlewares in the request pipeline. The filters are invoked in the order they were added to the service container. Filters may add middleware before or after passing control to the next filter, thus they append to the beginning or end of the app pipeline. -The sample app demonstrates how to register a middleware with `IStartupFilter`. The sample app includes a middleware that sets an options value from a query string parameter: +The following example demonstrates how to register a middleware with `IStartupFilter`. + +The `RequestSetOptionsMiddleware` middleware sets an options value from a query string parameter: -[!code-csharp[](startup/sample/RequestSetOptionsMiddleware.cs?name=snippet1)] +[!code-csharp[](startup/sample_snapshot/RequestSetOptionsMiddleware.cs?name=snippet1&highlight=21)] The `RequestSetOptionsMiddleware` is configured in the `RequestSetOptionsStartupFilter` class: -[!code-csharp[](startup/sample/RequestSetOptionsStartupFilter.cs?name=snippet1&highlight=7)] +[!code-csharp[](startup/sample_snapshot/RequestSetOptionsStartupFilter.cs?name=snippet1&highlight=7)] -The `IStartupFilter` is registered in the service container in [IWebHostBuilder.ConfigureServices](xref:Microsoft.AspNetCore.Hosting.IWebHostBuilder.ConfigureServices*) to demonstrate how the startup filter augments `Startup` from outside of the `Startup` class: +The `IStartupFilter` is registered in the service container in and augments `Startup` from outside of the `Startup` class: -[!code-csharp[](startup/sample/Program.cs?name=snippet1&highlight=4-5)] +[!code-csharp[](startup/sample_snapshot/Program2.cs?name=snippet1&highlight=4-5)] When a query string parameter for `option` is provided, the middleware processes the value assignment before the MVC middleware renders the response: @@ -115,7 +124,7 @@ Middleware execution order is set by the order of `IStartupFilter` registrations ## Add configuration at startup from an external assembly -An [IHostingStartup](/dotnet/api/microsoft.aspnetcore.hosting.ihostingstartup) implementation allows adding enhancements to an app at startup from an external assembly outside of the app's `Startup` class. For more information, see [Enhance an app from an external assembly](xref:fundamentals/configuration/platform-specific-configuration). +An implementation allows adding enhancements to an app at startup from an external assembly outside of the app's `Startup` class. For more information, see . ## Additional resources diff --git a/aspnetcore/fundamentals/startup/sample/.bowerrc b/aspnetcore/fundamentals/startup/sample/.bowerrc deleted file mode 100644 index 6406626abfef..000000000000 --- a/aspnetcore/fundamentals/startup/sample/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory": "wwwroot/lib" -} diff --git a/aspnetcore/fundamentals/startup/sample/Models/AppOptions.cs b/aspnetcore/fundamentals/startup/sample/Models/AppOptions.cs deleted file mode 100644 index fc673801794e..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Models/AppOptions.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace StartupFilterSample.Models -{ - public class AppOptions - { - public string Option { get; set; } = "Option Default Value"; - } -} diff --git a/aspnetcore/fundamentals/startup/sample/Pages/Error.cshtml b/aspnetcore/fundamentals/startup/sample/Pages/Error.cshtml deleted file mode 100644 index 0341fe884a5f..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Pages/Error.cshtml +++ /dev/null @@ -1,23 +0,0 @@ -@page -@model ErrorModel -@{ - ViewData["Title"] = "Error"; -} - -

Error.

-

An error occurred while processing your request.

- -@if (Model.ShowRequestId) -{ -

- Request ID: @Model.RequestId -

-} - -

Development Mode

-

- Swapping to the Development environment displays detailed information about the error that occurred. -

-

- The Development environment shouldn't be enabled for deployed applications. It can result in displaying sensitive information from exceptions to end users. For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development and restarting the app or adding .UseEnvironment("Development") to WebHost in Program.cs and restarting the app. -

diff --git a/aspnetcore/fundamentals/startup/sample/Pages/Error.cshtml.cs b/aspnetcore/fundamentals/startup/sample/Pages/Error.cshtml.cs deleted file mode 100644 index c6d7cba0f749..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Pages/Error.cshtml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Diagnostics; -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace StartupFilterSample.Pages -{ - public class ErrorModel : PageModel - { - public string RequestId { get; private set; } - - public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - - public void OnGet() - { - RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; - } - } -} diff --git a/aspnetcore/fundamentals/startup/sample/Pages/Index.cshtml b/aspnetcore/fundamentals/startup/sample/Pages/Index.cshtml deleted file mode 100644 index f1c1c401d3fb..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Pages/Index.cshtml +++ /dev/null @@ -1,25 +0,0 @@ -@page -@model IndexModel -@using Microsoft.Extensions.Options -@inject IOptions OptionsAccessor -@{ - ViewData["Title"] = "Startup Filter Sample"; -} - -

@ViewData["Title"]

- -
-
-
-
-

AppOptions

-
-
-

- @@OptionsAccessor.Value.Option: - @OptionsAccessor.Value.Option -

-
-
-
-
diff --git a/aspnetcore/fundamentals/startup/sample/Pages/Index.cshtml.cs b/aspnetcore/fundamentals/startup/sample/Pages/Index.cshtml.cs deleted file mode 100644 index 4dc905b137da..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Pages/Index.cshtml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace StartupFilterSample.Pages -{ - public class IndexModel : PageModel - { - public void OnGet() - { - } - } -} diff --git a/aspnetcore/fundamentals/startup/sample/Pages/_Layout.cshtml b/aspnetcore/fundamentals/startup/sample/Pages/_Layout.cshtml deleted file mode 100644 index 89b0a7603a60..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Pages/_Layout.cshtml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - @ViewData["Title"] - Startup Filter Sample - - - - - - - - - - - -
- @RenderBody() -
-
-

©@System.DateTime.Now.Year - Startup Filter Sample

-
-
- - - - - - - - - - - - - @RenderSection("Scripts", required: false) - - diff --git a/aspnetcore/fundamentals/startup/sample/Pages/_ViewImports.cshtml b/aspnetcore/fundamentals/startup/sample/Pages/_ViewImports.cshtml deleted file mode 100644 index 728974c9b448..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Pages/_ViewImports.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@using StartupFilterSample -@using StartupFilterSample.Models -@namespace StartupFilterSample.Pages -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/aspnetcore/fundamentals/startup/sample/Pages/_ViewStart.cshtml b/aspnetcore/fundamentals/startup/sample/Pages/_ViewStart.cshtml deleted file mode 100644 index a5f10045db97..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Pages/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "_Layout"; -} diff --git a/aspnetcore/fundamentals/startup/sample/README.md b/aspnetcore/fundamentals/startup/sample/README.md deleted file mode 100644 index 4822b7682937..000000000000 --- a/aspnetcore/fundamentals/startup/sample/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ASP.NET Core Startup filter sample - -This sample illustrates the use of [IStartupFilter](https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.hosting.istartupfilter). This sample demonstrates the features described in [Application Startup: Startup filters](https://docs.microsoft.com/aspnet/core/fundamentals/startup#startup-filters). diff --git a/aspnetcore/fundamentals/startup/sample/Startup.cs b/aspnetcore/fundamentals/startup/sample/Startup.cs deleted file mode 100644 index c6a2718b0a37..000000000000 --- a/aspnetcore/fundamentals/startup/sample/Startup.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; - -namespace StartupFilterSample -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - services.AddMvc(); - } - - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Error"); - } - - app.UseStaticFiles(); - app.UseMvc(); - } - } -} diff --git a/aspnetcore/fundamentals/startup/sample/StartupFilterSample.csproj b/aspnetcore/fundamentals/startup/sample/StartupFilterSample.csproj deleted file mode 100644 index 4bfa8acd8b30..000000000000 --- a/aspnetcore/fundamentals/startup/sample/StartupFilterSample.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - netcoreapp2.0 - - - - - - - diff --git a/aspnetcore/fundamentals/startup/sample/appsettings.Development.json b/aspnetcore/fundamentals/startup/sample/appsettings.Development.json deleted file mode 100644 index fa8ce71a97a3..000000000000 --- a/aspnetcore/fundamentals/startup/sample/appsettings.Development.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/aspnetcore/fundamentals/startup/sample/appsettings.Production.json b/aspnetcore/fundamentals/startup/sample/appsettings.Production.json deleted file mode 100644 index 05d41950658c..000000000000 --- a/aspnetcore/fundamentals/startup/sample/appsettings.Production.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Error", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/aspnetcore/fundamentals/startup/sample/appsettings.json b/aspnetcore/fundamentals/startup/sample/appsettings.json deleted file mode 100644 index 20aa907654ab..000000000000 --- a/aspnetcore/fundamentals/startup/sample/appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug" - } - } -} diff --git a/aspnetcore/fundamentals/startup/sample/bower.json b/aspnetcore/fundamentals/startup/sample/bower.json deleted file mode 100644 index b07e3cc5ae5d..000000000000 --- a/aspnetcore/fundamentals/startup/sample/bower.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "asp.net", - "private": true, - "dependencies": { - "bootstrap": "3.3.7", - "jquery": "2.2.0", - "jquery-validation": "1.14.0", - "jquery-validation-unobtrusive": "3.2.6" - } -} diff --git a/aspnetcore/fundamentals/startup/sample/bundleconfig.json b/aspnetcore/fundamentals/startup/sample/bundleconfig.json deleted file mode 100644 index 6d3f9a57aea2..000000000000 --- a/aspnetcore/fundamentals/startup/sample/bundleconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -// Configure bundling and minification for the project. -// More info at https://go.microsoft.com/fwlink/?LinkId=808241 -[ - { - "outputFileName": "wwwroot/css/site.min.css", - // An array of relative input file paths. Globbing patterns supported - "inputFiles": [ - "wwwroot/css/site.css" - ] - }, - { - "outputFileName": "wwwroot/js/site.min.js", - "inputFiles": [ - "wwwroot/js/site.js" - ], - // Optionally specify minification options - "minify": { - "enabled": true, - "renameLocals": true - }, - // Optionally generate .map file - "sourceMap": false - } -] diff --git a/aspnetcore/fundamentals/startup/sample/wwwroot/css/site.css b/aspnetcore/fundamentals/startup/sample/wwwroot/css/site.css deleted file mode 100644 index c08311ba3868..000000000000 --- a/aspnetcore/fundamentals/startup/sample/wwwroot/css/site.css +++ /dev/null @@ -1,21 +0,0 @@ -body { - padding-top: 50px; - padding-bottom: 20px; -} - -h1 { - font-size: 30px; -} - -h2 { - font-size: 24px; -} - -.body-content { - padding-left: 15px; - padding-right: 15px; -} - -.panel-body { - font-size: 16px; -} diff --git a/aspnetcore/fundamentals/startup/sample/wwwroot/favicon.ico b/aspnetcore/fundamentals/startup/sample/wwwroot/favicon.ico deleted file mode 100644 index a3a799985c43..000000000000 Binary files a/aspnetcore/fundamentals/startup/sample/wwwroot/favicon.ico and /dev/null differ diff --git a/aspnetcore/fundamentals/startup/sample/wwwroot/js/site.js b/aspnetcore/fundamentals/startup/sample/wwwroot/js/site.js deleted file mode 100644 index 82ecce7b4a78..000000000000 --- a/aspnetcore/fundamentals/startup/sample/wwwroot/js/site.js +++ /dev/null @@ -1 +0,0 @@ -// Write your Javascript code. diff --git a/aspnetcore/fundamentals/startup/snapshot_sample/Program.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Program1.cs similarity index 73% rename from aspnetcore/fundamentals/startup/snapshot_sample/Program.cs rename to aspnetcore/fundamentals/startup/sample_snapshot/Program1.cs index 6d2a45c2cc6f..965c59d07a9c 100644 --- a/aspnetcore/fundamentals/startup/snapshot_sample/Program.cs +++ b/aspnetcore/fundamentals/startup/sample_snapshot/Program1.cs @@ -17,29 +17,27 @@ public static IWebHostBuilder CreateWebHostBuilder(string[] args) => }) .ConfigureServices(services => { - services.AddMvc(); + ... }) .Configure(app => { var loggerFactory = app.ApplicationServices .GetRequiredService(); var logger = loggerFactory.CreateLogger(); + logger.LogInformation("Logged in Configure"); if (HostingEnvironment.IsDevelopment()) { - app.UseDeveloperExceptionPage(); + ... } else { - app.UseExceptionHandler("/Error"); + ... } - // Configuration is available during startup. Examples: - // Configuration["key"] - // Configuration["subsection:suboption1"] + var configValue = Configuration["subsection:suboption1"]; - app.UseMvcWithDefaultRoute(); - app.UseStaticFiles(); + ... }); } diff --git a/aspnetcore/fundamentals/startup/sample/Program.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Program2.cs similarity index 100% rename from aspnetcore/fundamentals/startup/sample/Program.cs rename to aspnetcore/fundamentals/startup/sample_snapshot/Program2.cs diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Program.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Program3.cs similarity index 88% rename from aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Program.cs rename to aspnetcore/fundamentals/startup/sample_snapshot/Program3.cs index f8eb8f2f6320..7014aad3ef4a 100644 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Program.cs +++ b/aspnetcore/fundamentals/startup/sample_snapshot/Program3.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -8,8 +8,9 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -namespace TodoApi +namespace WebApp { + #region snippet_Program public class Program { public static void Main(string[] args) @@ -21,4 +22,5 @@ public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup(); } + #endregion } diff --git a/aspnetcore/fundamentals/startup/sample/RequestSetOptionsMiddleware.cs b/aspnetcore/fundamentals/startup/sample_snapshot/RequestSetOptionsMiddleware.cs similarity index 100% rename from aspnetcore/fundamentals/startup/sample/RequestSetOptionsMiddleware.cs rename to aspnetcore/fundamentals/startup/sample_snapshot/RequestSetOptionsMiddleware.cs diff --git a/aspnetcore/fundamentals/startup/sample/RequestSetOptionsStartupFilter.cs b/aspnetcore/fundamentals/startup/sample_snapshot/RequestSetOptionsStartupFilter.cs similarity index 100% rename from aspnetcore/fundamentals/startup/sample/RequestSetOptionsStartupFilter.cs rename to aspnetcore/fundamentals/startup/sample_snapshot/RequestSetOptionsStartupFilter.cs diff --git a/aspnetcore/fundamentals/startup/snapshot_sample/Startup1.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Startup1.cs similarity index 100% rename from aspnetcore/fundamentals/startup/snapshot_sample/Startup1.cs rename to aspnetcore/fundamentals/startup/sample_snapshot/Startup1.cs diff --git a/aspnetcore/fundamentals/startup/snapshot_sample/Startup2.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Startup2.cs similarity index 100% rename from aspnetcore/fundamentals/startup/snapshot_sample/Startup2.cs rename to aspnetcore/fundamentals/startup/sample_snapshot/Startup2.cs diff --git a/aspnetcore/fundamentals/startup/sample_snapshot/Startup3.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Startup3.cs new file mode 100644 index 000000000000..0f813f01edb8 --- /dev/null +++ b/aspnetcore/fundamentals/startup/sample_snapshot/Startup3.cs @@ -0,0 +1,16 @@ +public void ConfigureServices(IServiceCollection services) +{ + // Add framework services. + services.AddDbContext(options => + options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); + + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.AddMvc(); + + // Add application services. + services.AddTransient(); + services.AddTransient(); +} diff --git a/aspnetcore/fundamentals/startup/sample_snapshot/Startup4.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Startup4.cs new file mode 100644 index 000000000000..183bc4d351e3 --- /dev/null +++ b/aspnetcore/fundamentals/startup/sample_snapshot/Startup4.cs @@ -0,0 +1,18 @@ +public void Configure(IApplicationBuilder app, IHostingEnvironment env) +{ + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Error"); + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseStaticFiles(); + app.UseCookiePolicy(); + + app.UseMvc(); +} diff --git a/aspnetcore/fundamentals/startup/sample_snapshot/Startup5.cs b/aspnetcore/fundamentals/startup/sample_snapshot/Startup5.cs new file mode 100644 index 000000000000..eaa9db49705d --- /dev/null +++ b/aspnetcore/fundamentals/startup/sample_snapshot/Startup5.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +public void Configure(IApplicationBuilder app, IHostingEnvironment env) +{ + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Error"); + } + + app.UseStaticFiles(); + + app.UseMvc(); +} diff --git a/aspnetcore/fundamentals/websockets.md b/aspnetcore/fundamentals/websockets.md index eab9df2f5a2b..1941ddb49e50 100644 --- a/aspnetcore/fundamentals/websockets.md +++ b/aspnetcore/fundamentals/websockets.md @@ -5,7 +5,7 @@ description: Learn how to get started with WebSockets in ASP.NET Core. monikerRange: '>= aspnetcore-1.1' ms.author: tdykstra ms.custom: mvc -ms.date: 11/06/2018 +ms.date: 01/17/2019 uid: fundamentals/websockets --- # WebSockets support in ASP.NET Core @@ -139,6 +139,12 @@ When accepting the WebSocket connection before beginning the loop, the middlewar ::: moniker range=">= aspnetcore-2.2" +### Handle client disconnects + +The server is not automatically informed when the client disconnects due to loss of connectivity. The server receives a disconnect message only if the client sends it, which can't be done if the internet connection is lost. If you want to take some action when that happens, set a timeout after nothing is received from the client within a certain time window. + +If the client isn't always sending messages and you don't want to timeout just because the connection goes idle, have the client use a timer to send a ping message every X seconds. On the server, if a message hasn't arrived within 2\*X seconds after the previous one, terminate the connection and report that the client disconnected. Wait for twice the expected time interval to leave extra time for network delays that might hold up the ping message. + ### WebSocket origin restriction The protections provided by CORS don't apply to WebSockets. Browsers do **not**: diff --git a/aspnetcore/host-and-deploy/aspnet-core-module.md b/aspnetcore/host-and-deploy/aspnet-core-module.md index 696de1c4adc2..fc3721c8de35 100644 --- a/aspnetcore/host-and-deploy/aspnet-core-module.md +++ b/aspnetcore/host-and-deploy/aspnet-core-module.md @@ -4,7 +4,7 @@ author: guardrex description: Learn how to configure the ASP.NET Core Module for hosting ASP.NET Core apps. ms.author: riande ms.custom: mvc -ms.date: 01/11/2019 +ms.date: 01/22/2019 uid: host-and-deploy/aspnet-core-module --- # ASP.NET Core Module @@ -280,7 +280,20 @@ For information on IIS sub-application configuration, see ` child element of an `` collection element. Environment variables set in this section take precedence over system environment variables. + +::: moniker-end + +::: moniker range="< aspnetcore-3.0" + +Environment variables can be specified for the process in the `processPath` attribute. Specify an environment variable with the `` child element of an `` collection element. + +> [!WARNING] +> Environment variables set in this section conflict with system environment variables set with the same name. If an environment variable is set in both the *web.config* file and at the system level in Windows, the value from the *web.config* file becomes appended to the system environment variable value (for example, `ASPNETCORE_ENVIRONMENT: Development;Development`), which prevents the app from starting. + +::: moniker-end The following example sets two environment variables. `ASPNETCORE_ENVIRONMENT` configures the app's environment to `Development`. A developer may temporarily set this value in the *web.config* file in order to force the [Developer Exception Page](xref:fundamentals/error-handling) to load when debugging an app exception. `CONFIG_DIR` is an example of a user-defined environment variable, where the developer has written code that reads the value on startup to form a path for loading the app's configuration file. @@ -317,6 +330,19 @@ The following example sets two environment variables. `ASPNETCORE_ENVIRONMENT` c ::: moniker-end +::: moniker range=">= aspnetcore-2.2" + +> [!NOTE] +> An alternative to setting the environment directly in *web.config* is to include the `` property in the publish profile (*.pubxml*) or project file. This approach sets the environment in *web.config* when the project is published: +> +> ```xml +> +> Development +> +> ``` + +::: moniker-end + > [!WARNING] > Only set the `ASPNETCORE_ENVIRONMENT` environment variable to `Development` on staging and testing servers that aren't accessible to untrusted networks, such as the Internet. @@ -403,7 +429,7 @@ The following sample `aspNetCore` element configures stdout logging for an app h ## Enhanced diagnostic logs -The ASP.NET Core Module provides is configurable to provide enhanced diagnostics logs. Add the `` element to the `` element in *web.config*. Setting the `debugLevel` to `TRACE` exposes a higher fidelity of diagnostic information: +The ASP.NET Core Module is configurable to provide enhanced diagnostics logs. Add the `` element to the `` element in *web.config*. Setting the `debugLevel` to `TRACE` exposes a higher fidelity of diagnostic information: ```xml * [ASP.NET Core Module GitHub repository (reference source)](https://github.com/aspnet/AspNetCoreModule) -* \ No newline at end of file +* diff --git a/aspnetcore/host-and-deploy/iis/modules.md b/aspnetcore/host-and-deploy/iis/modules.md index 0753eb11af3e..48dcb3bd06d3 100644 --- a/aspnetcore/host-and-deploy/iis/modules.md +++ b/aspnetcore/host-and-deploy/iis/modules.md @@ -4,7 +4,7 @@ author: guardrex description: Discover active and inactive IIS modules for ASP.NET Core apps and how to manage IIS modules. ms.author: riande ms.custom: mvc -ms.date: 11/30/2018 +ms.date: 01/17/2019 uid: host-and-deploy/iis/modules --- # IIS modules with ASP.NET Core @@ -99,13 +99,13 @@ For more information on disabling modules with configuration settings, follow th If opting to remove a module with a setting in *web.config*, unlock the module and unlock the `` section of *web.config* first: -1. Unlock the module at the server level. Select the IIS server in the IIS Manager **Connections** sidebar. Open the **Modules** in the **IIS** area. Select the module in the list. In the **Actions** sidebar on the right, select **Unlock**. Unlock as many modules as you plan to remove from *web.config* later. +1. Unlock the module at the server level. Select the IIS server in the IIS Manager **Connections** sidebar. Open the **Modules** in the **IIS** area. Select the module in the list. In the **Actions** sidebar on the right, select **Unlock**. If the action entry for the module appears as **Lock**, the module is already unlocked, and no action is required. Unlock as many modules as you plan to remove from *web.config* later. 2. Deploy the app without a `` section in *web.config*. If an app is deployed with a *web.config* containing the `` section without having unlocked the section first in the IIS Manager, the Configuration Manager throws an exception when attempting to unlock the section. Therefore, deploy the app without a `` section. -3. Unlock the `` section of *web.config*. In the **Connections** sidebar, select the website in **Sites**. In the **Management** area, open the **Configuration Editor**. Use the navigation controls to select the `system.webServer/modules` section. In the **Actions** sidebar on the right, select to **Unlock** the section. +3. Unlock the `` section of *web.config*. In the **Connections** sidebar, select the website in **Sites**. In the **Management** area, open the **Configuration Editor**. Use the navigation controls to select the `system.webServer/modules` section. In the **Actions** sidebar on the right, select to **Unlock** the section. If the action entry for the module section appears as **Lock Section**, the module section is already unlocked, and no action is required. -4. At this point, a `` section can be added to the *web.config* file with a `` element to remove the module from the app. Multiple `` elements can be added to remove multiple modules. If *web.config* changes are made on the server, immediately make the same changes to the project's *web.config* file locally. Removing a module this way won't affect the use of the module with other apps on the server. +4. Add a `` section to the app's local *web.config* file with a `` element to remove the module from the app. Add multiple `` elements to remove multiple modules. If *web.config* changes are made on the server, immediately make the same changes to the project's *web.config* file locally. Removing a module using this approach doesn't affect the use of the module with other apps on the server. ```xml @@ -116,6 +116,26 @@ If opting to remove a module with a setting in *web.config*, unlock the module a ``` + +In order to add or remove modules for IIS Express using *web.config*, modify *applicationHost.config* to unlock the `` section: + +1. Open *{APPLICATION ROOT}\\.vs\config\applicationhost.config*. + +1. Locate the `
` element for IIS modules and change `overrideModeDefault` from `Deny` to `Allow`: + + ```xml +
+ ``` + +1. Locate the `` section. For any modules that you wish to remove, set `lockItem` from `true` to `false`. In the following example, the CGI Module is unlocked: + + ```xml + + ``` + +1. After the `` section and individual modules are unlocked, you're free to add or remove IIS modules using the app's *web.config* file for running the app on IIS Express. An IIS module can also be removed with *Appcmd.exe*. Provide the `MODULE_NAME` and `APPLICATION_NAME` in the command: diff --git a/aspnetcore/host-and-deploy/visual-studio-publish-profiles.md b/aspnetcore/host-and-deploy/visual-studio-publish-profiles.md index 9199ecd6b3c7..ac843f9f6ff2 100644 --- a/aspnetcore/host-and-deploy/visual-studio-publish-profiles.md +++ b/aspnetcore/host-and-deploy/visual-studio-publish-profiles.md @@ -4,7 +4,7 @@ author: rick-anderson description: Learn how to create publish profiles in Visual Studio and use them for managing ASP.NET Core app deployments to various targets. ms.author: riande ms.custom: mvc -ms.date: 12/06/2018 +ms.date: 01/22/2019 uid: host-and-deploy/visual-studio-publish-profiles --- # Visual Studio publish profiles for ASP.NET Core app deployment @@ -331,6 +331,16 @@ dotnet msbuild "AzureWebApp.csproj" > [!NOTE] > The [dotnet msbuild](/dotnet/core/tools/dotnet-msbuild) command is available cross-platform and can compile ASP.NET Core apps on macOS and Linux. However, MSBuild on macOS and Linux isn't capable of deploying an app to Azure or other MSDeploy endpoint. MSDeploy is only available on Windows. +## Set the environment + +Include the `` property in the publish profile (*.pubxml*) or project file to set the app's [environment](xref:fundamentals/environments): + +```xml + + Development + +``` + ## Exclude files When publishing ASP.NET Core web apps, the build artifacts and contents of the *wwwroot* folder are included. `msbuild` supports [globbing patterns](https://gruntjs.com/configuring-tasks#globbing-patterns). For example, the following `` element excludes all text (*.txt*) files from the *wwwroot/content* folder and all its subfolders. diff --git a/aspnetcore/host-and-deploy/windows-service.md b/aspnetcore/host-and-deploy/windows-service.md index 84436d5be30b..95042d100edb 100644 --- a/aspnetcore/host-and-deploy/windows-service.md +++ b/aspnetcore/host-and-deploy/windows-service.md @@ -5,7 +5,7 @@ description: Learn how to host an ASP.NET Core app in a Windows Service. monikerRange: '>= aspnetcore-2.1' ms.author: tdykstra ms.custom: mvc -ms.date: 12/01/2018 +ms.date: 01/22/2019 uid: host-and-deploy/windows-service --- # Host ASP.NET Core in a Windows Service @@ -38,7 +38,9 @@ Based on your choice of [deployment type](#deployment-type), update the project #### Framework-dependent Deployment (FDD) -Add a Windows [Runtime Identifier (RID)](/dotnet/core/rid-catalog) to the `` that contains the target framework. Add the `` property set to `false`. Disable the creation of a *web.config* file by adding the `` property set to `true`. +Add a Windows [Runtime Identifier (RID)](/dotnet/core/rid-catalog) to the `` that contains the target framework. In the following example, the RID is set to `win7-x64`. Add the `` property set to `false`. These properties instruct the SDK to generate an executable (*.exe*) file for Windows. + +A *web.config* file, which is normally produced when publishing an ASP.NET Core app, is unnecessary for a Windows Services app. To disable the creation of the *web.config* file, add the `` property set to `true`. ::: moniker range=">= aspnetcore-2.2" @@ -55,6 +57,8 @@ Add a Windows [Runtime Identifier (RID)](/dotnet/core/rid-catalog) to the `` property set to `true`. This property provides the service with an activation path (an executable, *.exe*) for an FDD. + ```xml netcoreapp2.1 diff --git a/aspnetcore/includes/RP-EF/rp-over-mvc.md b/aspnetcore/includes/RP-EF/rp-over-mvc.md index 796110086729..1c6c8e8d6b73 100644 --- a/aspnetcore/includes/RP-EF/rp-over-mvc.md +++ b/aspnetcore/includes/RP-EF/rp-over-mvc.md @@ -5,6 +5,3 @@ This tutorial teaches ASP.NET Core MVC and Entity Framework Core with controller * Uses more efficient queries. * Is more current with the latest API. * Covers more features. -* Is the preferred approach for new application development. - -If you choose this tutorial over the [Razor Pages](xref:data/ef-rp/intro) version, let us know why in [this GitHub issue](https://github.com/aspnet/Docs/issues/6146). diff --git a/aspnetcore/includes/RP/model2.md b/aspnetcore/includes/RP/model2.md index 7702e5a7476f..a4eaeb0c3b42 100644 --- a/aspnetcore/includes/RP/model2.md +++ b/aspnetcore/includes/RP/model2.md @@ -22,6 +22,8 @@ Run the following .NET Core CLI command to add SQLite and CodeGeneration.Design ```console dotnet add package Microsoft.EntityFrameworkCore.SQLite dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design +dotnet add package Microsoft.EntityFrameworkCore.Design + ``` The `Microsoft.VisualStudio.Web.CodeGeneration.Design` package is required for scaffolding. @@ -41,4 +43,4 @@ Register the database context with the [dependency injection](xref:fundamentals/ [!code-csharp[](~/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie22/Startup.cs?name=snippet_UseSqlite&highlight=11-12)] -Build the project as a check for errors. \ No newline at end of file +Build the project as a check for errors. diff --git a/aspnetcore/includes/app-secrets/secrets-json-file.md b/aspnetcore/includes/app-secrets/secrets-json-file.md index 68adbb3f9136..7cb52b50b402 100644 --- a/aspnetcore/includes/app-secrets/secrets-json-file.md +++ b/aspnetcore/includes/app-secrets/secrets-json-file.md @@ -1,6 +1,9 @@ -```json -{ + +```json +{ + "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true", - "Movies:ServiceApiKey": "12345" + "Movies:ServiceApiKey": "12345" } -``` + +``` \ No newline at end of file diff --git a/aspnetcore/mvc/controllers/filters.md b/aspnetcore/mvc/controllers/filters.md index 31a7cf72f2e3..bcd63faac160 100644 --- a/aspnetcore/mvc/controllers/filters.md +++ b/aspnetcore/mvc/controllers/filters.md @@ -4,7 +4,7 @@ author: ardalis description: Learn how filters work and how to use them in ASP.NET Core MVC. ms.author: riande ms.custom: mvc -ms.date: 10/15/2018 +ms.date: 1/15/2019 uid: mvc/controllers/filters --- # Filters in ASP.NET Core @@ -13,9 +13,6 @@ By [Rick Anderson](https://twitter.com/RickAndMSFT), [Tom Dykstra](https://githu *Filters* in ASP.NET Core MVC allow you to run code before or after specific stages in the request processing pipeline. -> [!IMPORTANT] -> This topic does **not** apply to Razor Pages. ASP.NET Core 2.1 and later supports [IPageFilter](/dotnet/api/microsoft.aspnetcore.mvc.filters.ipagefilter?view=aspnetcore-2.0) and [IAsyncPageFilter](/dotnet/api/microsoft.aspnetcore.mvc.filters.iasyncpagefilter?view=aspnetcore-2.0) for Razor Pages. For more information, see [Filter methods for Razor Pages](xref:razor-pages/filter). - Built-in filters handle tasks such as: * Authorization (preventing access to resources a user isn't authorized for). @@ -26,7 +23,7 @@ Custom filters can be created to handle cross-cutting concerns. Filters can avoi [View or download sample from GitHub](https://github.com/aspnet/Docs/tree/master/aspnetcore/mvc/controllers/filters/sample). -## How do filters work? +## How filters work Filters run within the *MVC action invocation pipeline*, sometimes referred to as the *filter pipeline*. The filter pipeline runs after MVC selects the action to execute. @@ -40,7 +37,7 @@ Each filter type is executed at a different stage in the filter pipeline. * [Resource filters](#resource-filters) are the first to handle a request after authorization. They can run code before the rest of the filter pipeline, and after the rest of the pipeline has completed. They're useful to implement caching or otherwise short-circuit the filter pipeline for performance reasons. They run before model binding, so they can influence model binding. -* [Action filters](#action-filters) can run code immediately before and after an individual action method is called. They can be used to manipulate the arguments passed into an action and the result returned from the action. +* [Action filters](#action-filters) can run code immediately before and after an individual action method is called. They can be used to manipulate the arguments passed into an action and the result returned from the action. Action filters are not supported in Razor Pages. * [Exception filters](#exception-filters) are used to apply global policies to unhandled exceptions that occur before anything has been written to the response body. @@ -62,14 +59,13 @@ Asynchronous filters define a single On*Stage*ExecutionAsync method. This method [!code-csharp[](./filters/sample/src/FiltersSample/Filters/SampleAsyncActionFilter.cs?highlight=6,8-10,13)] -You can implement interfaces for multiple filter stages in a single class. For example, the [ActionFilterAttribute](/dotnet/api/microsoft.aspnetcore.mvc.filters.actionfilterattribute?view=aspnetcore-2.0) class implements `IActionFilter`, `IResultFilter`, and their async equivalents. +You can implement interfaces for multiple filter stages in a single class. For example, the class implements `IActionFilter`, `IResultFilter`, and their async equivalents. > [!NOTE] -> Implement **either** the synchronous or the async version of a filter interface, not both. The framework checks first to see if the filter implements the async interface, and if so, it calls that. If not, it calls the synchronous interface's method(s). If you were to implement both interfaces on one class, only the async method would be called. When using abstract classes like [ActionFilterAttribute](/dotnet/api/microsoft.aspnetcore.mvc.filters.actionfilterattribute?view=aspnetcore-2.0) you would override only the synchronous methods or the async method for each filter type. +> Implement **either** the synchronous or the async version of a filter interface, not both. The framework checks first to see if the filter implements the async interface, and if so, it calls that. If not, it calls the synchronous interface's method(s). If you were to implement both interfaces on one class, only the async method would be called. When using abstract classes like you would override only the synchronous methods or the async method for each filter type. ### IFilterFactory - -[IFilterFactory](/dotnet/api/microsoft.aspnetcore.mvc.filters.ifilterfactory) implements [IFilterMetadata](/dotnet/api/microsoft.aspnetcore.mvc.filters.ifiltermetadata). Therefore, an `IFilterFactory` instance can be used as an `IFilterMetadata` instance anywhere in the filter pipeline. When the framework prepares to invoke the filter, it attempts to cast it to an `IFilterFactory`. If that cast succeeds, the [CreateInstance](/dotnet/api/microsoft.aspnetcore.mvc.filters.ifilterfactory.createinstance) method is called to create the `IFilterMetadata` instance that will be invoked. This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts. +[IFilterFactory](/dotnet/api/microsoft.aspnetcore.mvc.filters.ifilterfactory) implements . Therefore, an `IFilterFactory` instance can be used as an `IFilterMetadata` instance anywhere in the filter pipeline. When the framework prepares to invoke the filter, it attempts to cast it to an `IFilterFactory`. If that cast succeeds, the [CreateInstance](/dotnet/api/microsoft.aspnetcore.mvc.filters.ifilterfactory.createinstance) method is called to create the `IFilterMetadata` instance that will be invoked. This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts. You can implement `IFilterFactory` on your own attribute implementations as another approach to creating filters: @@ -275,6 +271,9 @@ The [short circuiting resource filter](#short-circuiting-resource-filter) shown ## Action filters +> [!IMPORTANT] +> Action filters do **not** apply to Razor Pages. Razor Pages supports and . For more information, see [Filter methods for Razor Pages](xref:razor-pages/filter). + *Action filters*: * Implement either the `IActionFilter` or `IAsyncActionFilter` interface. @@ -284,13 +283,13 @@ Here's a sample action filter: [!code-csharp[](./filters/sample/src/FiltersSample/Filters/SampleActionFilter.cs?name=snippet_ActionFilter)] -The [ActionExecutingContext](/dotnet/api/microsoft.aspnetcore.mvc.filters.actionexecutingcontext) provides the following properties: +The provides the following properties: * `ActionArguments` - lets you manipulate the inputs to the action. * `Controller` - lets you manipulate the controller instance. * `Result` - setting this short-circuits execution of the action method and subsequent action filters. Throwing an exception also prevents execution of the action method and subsequent filters, but is treated as a failure instead of a successful result. -The [ActionExecutedContext](/dotnet/api/microsoft.aspnetcore.mvc.filters.actionexecutedcontext) provides `Controller` and `Result` plus the following properties: +The provides `Controller` and `Result` plus the following properties: * `Canceled` - will be true if the action execution was short-circuited by another filter. * `Exception` - will be non-null if the action or a subsequent action filter threw an exception. Setting this property to null effectively 'handles' an exception, and `Result` will be executed as if it were returned from the action method normally. @@ -386,4 +385,5 @@ Middleware filters run at the same stage of the filter pipeline as Resource filt ## Next actions -To experiment with filters, [download, test and modify the sample](https://github.com/aspnet/Docs/tree/master/aspnetcore/mvc/controllers/filters/sample). +* See [Filter methods for Razor Pages](xref:razor-pages/filter) +* To experiment with filters, [download, test and modify the Github sample](https://github.com/aspnet/Docs/tree/master/aspnetcore/mvc/controllers/filters/sample). diff --git a/aspnetcore/mvc/controllers/routing.md b/aspnetcore/mvc/controllers/routing.md index 09fb3fd23377..e42d3cfa40a2 100644 --- a/aspnetcore/mvc/controllers/routing.md +++ b/aspnetcore/mvc/controllers/routing.md @@ -3,14 +3,14 @@ title: Routing to controller actions in ASP.NET Core author: rick-anderson description: Learn how ASP.NET Core MVC uses Routing Middleware to match URLs of incoming requests and map them to actions. ms.author: riande -ms.date: 09/17/2018 +ms.date: 01/24/2019 uid: mvc/controllers/routing --- # Routing to controller actions in ASP.NET Core By [Ryan Nowak](https://github.com/rynowak) and [Rick Anderson](https://twitter.com/RickAndMSFT) -ASP.NET Core MVC uses the Routing [middleware](xref:fundamentals/middleware/index) to match the URLs of incoming requests and map them to actions. Routes are defined in startup code or attributes. Routes describe how URL paths should be matched to actions. Routes are also used to generate URLs (for links) sent out in responses. +ASP.NET Core MVC uses the Routing [middleware](xref:fundamentals/middleware/index) to match the URLs of incoming requests and map them to actions. Routes are defined in startup code or attributes. Routes describe how URL paths should be matched to actions. Routes are also used to generate URLs (for links) sent out in responses. Actions are either conventionally routed or attribute routed. Placing a route on the controller or the action makes it attribute routed. See [Mixed routing](#routing-mixed-ref-label) for more information. @@ -185,7 +185,6 @@ If multiple routes match, and MVC can't find a 'best' route, it will throw an `A The strings `"blog"` and `"default"` in the following examples are route names: - ```csharp app.UseMvc(routes => { @@ -333,7 +332,7 @@ public class ProductsApiController : Controller In this example the URL path `/products` can match `ProductsApi.ListProducts`, and the URL path `/products/5` can match `ProductsApi.GetProduct(int)`. Both of these actions only match HTTP `GET` because they're decorated with the `HttpGetAttribute`. -Route templates applied to an action that begin with a `/` don't get combined with route templates applied to the controller. This example matches a set of URL paths similar to the *default route*. +Route templates applied to an action that begin with `/` or `~/` don't get combined with route templates applied to the controller. This example matches a set of URL paths similar to the *default route*. ```csharp [Route("Home")] diff --git a/aspnetcore/mvc/views/razor.md b/aspnetcore/mvc/views/razor.md index 62c4582f3e04..6f26ac0cfc40 100644 --- a/aspnetcore/mvc/views/razor.md +++ b/aspnetcore/mvc/views/razor.md @@ -539,7 +539,7 @@ public class Pet ```cshtml @{ - Func petTemplate = @

You have a pet named @item.Name.

; + Func petTemplate = @

You have a pet named @item.Name.

; var pets = new List { @@ -555,7 +555,7 @@ The template is rendered with `pets` supplied by a `foreach` statement: ```cshtml @foreach (var pet in pets) { - @petTemplate2(pet) + @petTemplate(pet) } ``` diff --git a/aspnetcore/mvc/views/tag-helpers/authoring.md b/aspnetcore/mvc/views/tag-helpers/authoring.md index a33e7adaddaf..26dc05589669 100644 --- a/aspnetcore/mvc/views/tag-helpers/authoring.md +++ b/aspnetcore/mvc/views/tag-helpers/authoring.md @@ -91,7 +91,7 @@ Update the `EmailTagHelper` class with the following: [!code-csharp[](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/TagHelpers/EmailTagHelperMailTo.cs?range=6-22)] -* Pascal-cased class and property names for tag helpers are translated into their [lower kebab case](https://stackoverflow.com/questions/11273282/whats-the-name-for-dash-separated-case/12273101). Therefore, to use the `MailTo` attribute, you'll use `` equivalent. +* Pascal-cased class and property names for tag helpers are translated into their [kebab case](https://stackoverflow.com/questions/11273282/whats-the-name-for-dash-separated-case/12273101). Therefore, to use the `MailTo` attribute, you'll use `` equivalent. * The last line sets the completed content for our minimally functional tag helper. @@ -185,7 +185,7 @@ You can also use the `[HtmlTargetElement]` to change the name of the targeted el [!code-csharp[](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/TagHelpers/WebsiteInformationTagHelper.cs)] - * As mentioned previously, tag helpers translates Pascal-cased C# class names and properties for tag helpers into [lower kebab case](http://wiki.c2.com/?KebabCase). Therefore, to use the `WebsiteInformationTagHelper` in Razor, you'll write ``. + * As mentioned previously, tag helpers translates Pascal-cased C# class names and properties for tag helpers into [kebab case](http://wiki.c2.com/?KebabCase). Therefore, to use the `WebsiteInformationTagHelper` in Razor, you'll write ``. * You are not explicitly identifying the target element with the `[HtmlTargetElement]` attribute, so the default of `website-information` will be targeted. If you applied the following attribute (note it's not kebab case but matches the class name): @@ -193,7 +193,7 @@ You can also use the `[HtmlTargetElement]` to change the name of the targeted el [HtmlTargetElement("WebsiteInformation")] ``` - The lower kebab case tag `` wouldn't match. If you want use the `[HtmlTargetElement]` attribute, you would use kebab case as shown below: + The kebab case tag `` wouldn't match. If you want use the `[HtmlTargetElement]` attribute, you would use kebab case as shown below: ```csharp [HtmlTargetElement("Website-Information")] @@ -209,12 +209,12 @@ You can also use the `[HtmlTargetElement]` to change the name of the targeted el 1. Add the following markup to the *About.cshtml* view. The highlighted markup displays the web site information. - [!code-html[](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml?highlight=1,12-999)] + [!code-html[](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml?highlight=1,4-8, 18-999)] > [!NOTE] > In the Razor markup shown below: > - > [!code-html[](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml?range=13-17)] + > [!code-html[](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml?range=18-18)] > > Razor knows the `info` attribute is a class, not a string, and you want to write C# code. Any non-string tag helper attribute should be written without the `@` character. diff --git a/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/TagHelpers/EmailTagHelperMailTo.cs b/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/TagHelpers/EmailTagHelperMailTo.cs index 3c520494212e..026cd71671c6 100644 --- a/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/TagHelpers/EmailTagHelperMailTo.cs +++ b/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/TagHelpers/EmailTagHelperMailTo.cs @@ -8,7 +8,7 @@ public class EmailTagHelper : TagHelper private const string EmailDomain = "contoso.com"; // Can be passed via . - // Pascal case gets translated into lower-kebab-case. + // PascalCase gets translated into kebab-case. public string MailTo { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) diff --git a/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml b/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml index 552e1638c41d..1c3e390a83ef 100644 --- a/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml +++ b/aspnetcore/mvc/views/tag-helpers/authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml @@ -1,6 +1,11 @@ @using AuthoringTagHelpers.Models @{ ViewData["Title"] = "About"; + WebsiteContext webContext = new WebsiteContext { + Version = new Version(1, 3), + CopyrightYear = 1638, + Approved = true, + TagsToShow = 131 }; }

@ViewData["Title"].

@ViewData["Message"]

@@ -10,8 +15,4 @@ Is this bold?

web site info

- \ No newline at end of file + diff --git a/aspnetcore/mvc/views/view-compilation.md b/aspnetcore/mvc/views/view-compilation.md index 92a654f0e296..8f939f7496f1 100644 --- a/aspnetcore/mvc/views/view-compilation.md +++ b/aspnetcore/mvc/views/view-compilation.md @@ -5,7 +5,7 @@ description: Learn about the benefits of precompiling Razor files and how to acc monikerRange: '>= aspnetcore-1.1' ms.author: riande ms.custom: mvc -ms.date: 05/17/2018 +ms.date: 01/23/2019 uid: mvc/views/view-compilation --- # Razor file compilation in ASP.NET Core @@ -90,6 +90,25 @@ A *.PrecompiledViews.dll* file, containing the compiled Razor file ::: moniker-end +## Recompile Razor files on change + +The `AllowRecompilingViewsOnFileChange` gets or sets a value that determines if Razor files (Razor views and Razor Pages) are recompiled and updated if files change on disk. + +When set to `true`, [IFileProvider.Watch](xref:Microsoft.Extensions.FileProviders.IFileProvider.Watch*) watches for changes to Razor files in configured instances. + +The default value is `true` for: + +* ASP.NET Core 2.1 or earlier apps. +* ASP.NET Core 2.2 or later apps in the Development environment. + +`AllowRecompilingViewsOnFileChange` is associated with a compatibility switch and can provide different behavior depending on the configured compatibility version for the app. Configuring the app by setting `AllowRecompilingViewsOnFileChange` takes precedence over the value implied by the app's compatibility version. + +If the app's compatibility version is set to or earlier, `AllowRecompilingViewsOnFileChange` is set to `true` unless explicitly configured. + +If the app's compatibility version is set to `CompatibilityVersion.Version_2_2` or later, `AllowRecompilingViewsOnFileChange` is set to `false` unless the environment is Development or the value is explicitly configured. + +For guidance and examples of setting the app's compatibility version, see . + ## Additional resources ::: moniker range="= aspnetcore-1.1" diff --git a/aspnetcore/mvc/views/view-components.md b/aspnetcore/mvc/views/view-components.md index 8996800dd90a..0362cf285b51 100644 --- a/aspnetcore/mvc/views/view-components.md +++ b/aspnetcore/mvc/views/view-components.md @@ -14,7 +14,7 @@ By [Rick Anderson](https://twitter.com/RickAndMSFT) ## View components -View components are similar to partial views, but they're much more powerful. View components don't use model binding, and only depend on the data provided when calling into it. This article was written using ASP.NET Core MVC, but view components also work with Razor Pages. +View components are similar to partial views, but they're much more powerful. View components don't use model binding, and only depend on the data provided when calling into it. This article was written using controllers and views, but view components also work with Razor Pages. A view component: @@ -85,9 +85,9 @@ To use the view component, call the following inside a view: @await Component.InvokeAsync("Name of view component", {Anonymous Type Containing Parameters}) ``` -The parameters will be passed to the `InvokeAsync` method. The `PriorityList` view component developed in the article is invoked from the *Views/Todo/Index.cshtml* view file. In the following, the `InvokeAsync` method is called with two parameters: +The parameters will be passed to the `InvokeAsync` method. The `PriorityList` view component developed in the article is invoked from the *Views/ToDo/Index.cshtml* view file. In the following, the `InvokeAsync` method is called with two parameters: -[!code-cshtml[](view-components/sample/ViewCompFinal/Views/Todo/IndexFinal.cshtml?range=35)] +[!code-cshtml[](view-components/sample/ViewCompFinal/Views/ToDo/IndexFinal.cshtml?range=35)] ::: moniker range=">= aspnetcore-1.1" @@ -95,9 +95,9 @@ The parameters will be passed to the `InvokeAsync` method. The `PriorityList` vi For ASP.NET Core 1.1 and higher, you can invoke a view component as a [Tag Helper](xref:mvc/views/tag-helpers/intro): -[!code-cshtml[](view-components/sample/ViewCompFinal/Views/Todo/IndexTagHelper.cshtml?range=37-38)] +[!code-cshtml[](view-components/sample/ViewCompFinal/Views/ToDo/IndexTagHelper.cshtml?range=37-38)] -Pascal-cased class and method parameters for Tag Helpers are translated into their [lower kebab case](https://stackoverflow.com/questions/11273282/whats-the-name-for-dash-separated-case/12273101). The Tag Helper to invoke a view component uses the `` element. The view component is specified as follows: +Pascal-cased class and method parameters for Tag Helpers are translated into their [kebab case](https://stackoverflow.com/questions/11273282/whats-the-name-for-dash-separated-case/12273101). The Tag Helper to invoke a view component uses the `` element. The view component is specified as follows: ```cshtml + -[!code-cshtml[](view-components/sample/ViewCompFinal/Views/Todo/IndexFinal.cshtml?range=35)] +[!code-cshtml[](view-components/sample/ViewCompFinal/Views/ToDo/IndexFinal.cshtml?range=35)] Run the app and verify PVC view. @@ -216,7 +216,7 @@ If the PVC view isn't rendered, verify you are calling the view component with a ### Examine the view path * Change the priority parameter to three or less so the priority view isn't returned. -* Temporarily rename the *Views/Todo/Components/PriorityList/Default.cshtml* to *1Default.cshtml*. +* Temporarily rename the *Views/ToDo/Components/PriorityList/Default.cshtml* to *1Default.cshtml*. * Test the app, you'll get the following error: ``` @@ -227,8 +227,8 @@ If the PVC view isn't rendered, verify you are calling the view component with a EnsureSuccessful ``` -* Copy *Views/Todo/Components/PriorityList/1Default.cshtml* to *Views/Shared/Components/PriorityList/Default.cshtml*. -* Add some markup to the *Shared* Todo view component view to indicate the view is from the *Shared* folder. +* Copy *Views/ToDo/Components/PriorityList/1Default.cshtml* to *Views/Shared/Components/PriorityList/Default.cshtml*. +* Add some markup to the *Shared* ToDo view component view to indicate the view is from the *Shared* folder. * Test the **Shared** component view. ![ToDo output with Shared component view](view-components/_static/shared.png) @@ -241,7 +241,7 @@ If you want compile time safety, you can replace the hard-coded view component n Add a `using` statement to your Razor view file, and use the `nameof` operator: -[!code-cshtml[](view-components/sample/ViewCompFinal/Views/Todo/IndexNameof.cshtml?range=1-6,35-)] +[!code-cshtml[](view-components/sample/ViewCompFinal/Views/ToDo/IndexNameof.cshtml?range=1-6,35-)] ## Perform synchronous work diff --git a/aspnetcore/mvc/views/view-components/sample/StarterViewComp/Views/Todo/Index.cshtml b/aspnetcore/mvc/views/view-components/sample/StarterViewComp/Views/ToDo/Index.cshtml similarity index 100% rename from aspnetcore/mvc/views/view-components/sample/StarterViewComp/Views/Todo/Index.cshtml rename to aspnetcore/mvc/views/view-components/sample/StarterViewComp/Views/ToDo/Index.cshtml diff --git a/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/Components/PriorityList/Default.cshtml b/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/Components/PriorityList/Default.cshtml similarity index 100% rename from aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/Components/PriorityList/Default.cshtml rename to aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/Components/PriorityList/Default.cshtml diff --git a/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/Index.cshtml b/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/Index.cshtml similarity index 100% rename from aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/Index.cshtml rename to aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/Index.cshtml diff --git a/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexFinal.cshtml b/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexFinal.cshtml similarity index 100% rename from aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexFinal.cshtml rename to aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexFinal.cshtml diff --git a/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexFirst.cshtml b/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexFirst.cshtml similarity index 100% rename from aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexFirst.cshtml rename to aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexFirst.cshtml diff --git a/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexNameof.cshtml b/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexNameof.cshtml similarity index 100% rename from aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexNameof.cshtml rename to aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexNameof.cshtml diff --git a/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexTagHelper.cshtml b/aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexTagHelper.cshtml similarity index 100% rename from aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/Todo/IndexTagHelper.cshtml rename to aspnetcore/mvc/views/view-components/sample/ViewCompFinal/Views/ToDo/IndexTagHelper.cshtml diff --git a/aspnetcore/razor-pages/sdk.md b/aspnetcore/razor-pages/sdk.md index 4ad176b8ec3d..d842c8d28147 100644 --- a/aspnetcore/razor-pages/sdk.md +++ b/aspnetcore/razor-pages/sdk.md @@ -75,7 +75,7 @@ The properties and items in the following table are used to configure inputs and | `RazorTargetName` | File name (without extension) of the assembly produced by Razor. | | `RazorOutputPath` | The Razor output directory. | | `RazorCompileToolset` | Used to determine the toolset used to build the Razor assembly. Valid values are `Implicit`, `RazorSDK`, and `PrecompilationTool`. | -| `EnableDefaultContentItems` | When `true`, includes certain file types, such as *.cshtml* files, as content in the project. When referenced via `Microsoft.NET.Sdk.Web`, files under *wwwroot* and config files are also included. | +| [EnableDefaultContentItems](https://github.com/aspnet/websdk/blob/rel-2.0.0/src/ProjectSystem/Microsoft.NET.Sdk.Web.ProjectSystem.Targets/netstandard1.0/Microsoft.NET.Sdk.Web.ProjectSystem.targets#L21) | Default is `true`. When `true`, includes *web.config*, *.json*, and *.cshtml* files as content in the project. When referenced via `Microsoft.NET.Sdk.Web`, files under *wwwroot* and config files are also included. | | `EnableDefaultRazorGenerateItems` | When `true`, includes *.cshtml* files from `Content` items in `RazorGenerate` items. | | `GenerateRazorTargetAssemblyInfo` | When `true`, generates a *.cs* file containing attributes specified by `RazorAssemblyAttribute` and includes the file in the compile output. | | `EnableDefaultRazorTargetAssemblyInfoAttributes` | When `true`, adds a default set of assembly attributes to `RazorAssemblyAttribute`. | @@ -85,6 +85,8 @@ The properties and items in the following table are used to configure inputs and | `EmbedRazorGenerateSources` | When `true`, adds RazorGenerate (*.cshtml*) items as embedded files to the generated Razor assembly. Defaults to `false`. | | `UseRazorBuildServer` | When `true`, uses a persistent build server process to offload code generation work. Defaults to the value of `UseSharedCompilation`. | +For more information on properties, see [MSBuild properties](/visualstudio/msbuild/msbuild-properties). + ### Targets The Razor SDK defines two primary targets: diff --git a/aspnetcore/release-notes/aspnetcore-2.2.md b/aspnetcore/release-notes/aspnetcore-2.2.md index 9f0ba2841e53..361bdd832c38 100644 --- a/aspnetcore/release-notes/aspnetcore-2.2.md +++ b/aspnetcore/release-notes/aspnetcore-2.2.md @@ -51,7 +51,7 @@ ASP.NET Core 2.2 adds support for HTTP/2. HTTP/2 is a major revision of the HTTP protocol. Some of the notable features of HTTP/2 are support for header compression and fully multiplexed streams over a single connection. While HTTP/2 preserves HTTP’s semantics (HTTP headers, methods, etc) it's a breaking change from HTTP/1.x on how this data is framed and sent over the wire. -As a consequence of this change in framing, servers and clients need to negotiate the protocol version used. Application-Layer Protocol Negotiation (ALPN) is a TLS extension that allows the server and client negotiate the protocol version used as part of their TLS handshake. While it is possible to have prior knowledge between the server and the client on the protocol, all major browsers support ALPN as the only way to establish an HTTP/2 connection. +As a consequence of this change in framing, servers and clients need to negotiate the protocol version used. Application-Layer Protocol Negotiation (ALPN) is a TLS extension that allows the server and client to negotiate the protocol version used as part of their TLS handshake. While it is possible to have prior knowledge between the server and the client on the protocol, all major browsers support ALPN as the only way to establish an HTTP/2 connection. For more information, see [HTTP/2 support](xref:fundamentals/servers/index?view=aspnetcore-2.2#http2-support). diff --git a/aspnetcore/security/authentication/accconfirm.md b/aspnetcore/security/authentication/accconfirm.md index 4dfe7443909a..213b2cf00b49 100644 --- a/aspnetcore/security/authentication/accconfirm.md +++ b/aspnetcore/security/authentication/accconfirm.md @@ -249,6 +249,6 @@ The two accounts have been combined. You are able to log on with either account. Enabling account confirmation on a site with users locks out all the existing users. Existing users are locked out because their accounts aren't confirmed. To work around existing user lockout, use one of the following approaches: * Update the database to mark all existing users as being confirmed. -* Confirm exiting users. For example, batch-send emails with confirmation links. +* Confirm existing users. For example, batch-send emails with confirmation links. ::: moniker-end diff --git a/aspnetcore/security/authentication/identity-enable-qrcodes.md b/aspnetcore/security/authentication/identity-enable-qrcodes.md index aaede7d634a6..ccb531ede8ea 100644 --- a/aspnetcore/security/authentication/identity-enable-qrcodes.md +++ b/aspnetcore/security/authentication/identity-enable-qrcodes.md @@ -21,6 +21,8 @@ ASP.NET Core ships with support for authenticator applications for individual au The ASP.NET Core web app templates support authenticators, but don't provide support for QRCode generation. QRCode generators ease the setup of 2FA. This document will guide you through adding [QR Code](https://wikipedia.org/wiki/QR_code) generation to the 2FA configuration page. +Two factor authentication does not happen using an external authentication provider, such as [Google](xref:security/authentication/google-logins) or [Facebook](xref:security/authentication/facebook-logins). External logins are protected by whatever mechanism the external login provider provides. Consider, for example, the [Microsoft](xref:security/authentication/microsoft-logins) authentication provider requires a hardware key or another 2FA approach. If the default templates enforced "local" 2FA then users would be required to satisfy two 2FA approaches, which is not a commonly used scenario. + ## Adding QR Codes to the 2FA configuration page These instructions use *qrcode.js* from the https://davidshimjs.github.io/qrcodejs/ repo. diff --git a/aspnetcore/security/authentication/samples.md b/aspnetcore/security/authentication/samples.md new file mode 100644 index 000000000000..55c935fe01bd --- /dev/null +++ b/aspnetcore/security/authentication/samples.md @@ -0,0 +1,28 @@ +--- +title: Authentication samples for ASP.NET Core +author: rick-anderson +description: Provides links to the authentication samples in the ASP.NET Core repository. +ms.author: riande +ms.date: 01/31/2019 +uid: security/authentication/samples +--- +# Authentication samples for ASP.NET Core + +By [Rick Anderson](https://twitter.com/RickAndMSFT) + +The [ASP.NET Core repository](https://github.com/aspnet/AspNetCore) contains the following authentication samples in the *AspNetCore/src/Security/samples* folder: + +* [Claims transformation](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/ClaimsTransformation) +* [Cookie authentication](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/Cookies) +* [Custom policy provider - IAuthorizationPolicyProvider](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/CustomPolicyProvider) +* [Dynamic authentication schemes and options](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/DynamicSchemes) +* [External claims](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/Identity.ExternalClaims) +* [Selecting between cookie and another authentication scheme based on the request](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/PathSchemeSelection) +* [Restricts access to static files](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/StaticFilesAuth) + +## Run the samples + +* Select a [branch](https://github.com/aspnet/AspNetCore). For example, `release/2.2` +* Clone or download the [ASP.NET Core repository](https://github.com/aspnet/AspNetCore). +* Verify you have installed the [.NET Core SDK](https://www.microsoft.com/net/download/all) version matching the clone of the ASP.NET Core repository. +* Navigate to a sample in *AspNetCore/src/Security/samples* and run the sample with `dotnet run`. diff --git a/aspnetcore/security/authentication/social/google-logins.md b/aspnetcore/security/authentication/social/google-logins.md index 3443ca4a036c..c66bd8790859 100644 --- a/aspnetcore/security/authentication/social/google-logins.md +++ b/aspnetcore/security/authentication/social/google-logins.md @@ -4,156 +4,66 @@ author: rick-anderson description: This tutorial demonstrates the integration of Google account user authentication into an existing ASP.NET Core app. ms.author: riande ms.custom: "mvc, seodec18" -ms.date: 11/11/2018 +ms.date: 1/11/2019 uid: security/authentication/google-logins --- # Google external login setup in ASP.NET Core By [Valeriy Novytskyy](https://github.com/01binary) and [Rick Anderson](https://twitter.com/RickAndMSFT) -This tutorial shows you how to enable your users to sign in with their Google+ account using a sample ASP.NET Core 2.0 project created on the [previous page](xref:security/authentication/social/index). We start by following the [official steps](https://developers.google.com/identity/sign-in/web/devconsole-project) to create a new app in Google API Console. +In January 2019 Google started to [shut down](https://developers.google.com/+/api-shutdown) Google+ sign in and developers must move to a new Google sign in system by March. The ASP.NET Core 2.1 and 2.2 packages for Google Authentication will be updated in February to accommodate the changes. For more information and temporary mitigations for ASP.NET Core, see [this GitHub issue](https://github.com/aspnet/AspNetCore/issues/6486). This tutorial has been updated with the new setup process. -## Create the app in Google API Console +This tutorial shows you how to enable users to sign in with their Google account using the ASP.NET Core 2.2 project created on the [previous page](xref:security/authentication/social/index). -* Navigate to [https://console.developers.google.com/projectselector/apis/library](https://console.developers.google.com/projectselector/apis/library) and sign in. If you don't already have a Google account, use **More options** > **[Create account](https://accounts.google.com/SignUpWithoutGmail?service=cloudconsole&continue=https%3A%2F%2Fconsole.developers.google.com%2Fprojectselector%2Fapis%2Flibrary<mpl=api)** link to create one: +## Create a Google API Console project and client ID -![Google API Console](index/_static/GoogleConsoleLogin.png) - -* You are redirected to **API Manager Library** page: - -![Landing on the API Manager Library page](index/_static/GoogleConsoleSwitchboard.png) - -* Tap **Create** and enter your **Project name**: - -![New Project dialog](index/_static/GoogleConsoleNewProj.png) - -* After accepting the dialog, you are redirected back to the Library page allowing you to choose features for your new app. Find **Google+ API** in the list and click on its link to add the API feature: - -![Search for "Google+ API" in the API Manager Library page](index/_static/GoogleConsoleChooseApi.png) - -* The page for the newly added API is displayed. Tap **Enable** to add Google+ sign in feature to your app: - -![Landing on the API Manager Google+API page](index/_static/GoogleConsoleEnableApi.png) - -* After enabling the API, tap **Create credentials** to configure the secrets: - -![Create credentials button on API Manager Google+API page](index/_static/GoogleConsoleGoCredentials.png) - -* Choose: - * **Google+ API** - * **Web server (e.g. node.js, Tomcat)**, and - * **User data**: - -![API Manager Credentials page: Find out what kind of credentials you need panel](index/_static/GoogleConsoleChooseCred.png) - -* Tap **What credentials do I need?** which takes you to the second step of app configuration, **Create an OAuth 2.0 client ID**: - -![API Manager Credentials page: Create an OAuth 2.0 client ID](index/_static/GoogleConsoleCreateClient.png) - -* Because we are creating a Google+ project with just one feature (sign in), we can enter the same **Name** for the OAuth 2.0 client ID as the one we used for the project. - -* Enter your development URI with `/signin-google` appended into the **Authorized redirect URIs** field (for example: `https://localhost:44320/signin-google`). The Google authentication configured later in this tutorial will automatically handle requests at `/signin-google` route to implement the OAuth flow. - -> [!NOTE] -> The URI segment `/signin-google` is set as the default callback of the Google authentication provider. You can change the default callback URI while configuring the Google authentication middleware via the inherited [RemoteAuthenticationOptions.CallbackPath](/dotnet/api/microsoft.aspnetcore.authentication.remoteauthenticationoptions.callbackpath) property of the [GoogleOptions](/dotnet/api/microsoft.aspnetcore.authentication.google.googleoptions) class. - -* Press TAB to add the **Authorized redirect URIs** entry. - -* Tap **Create client ID**, which takes you to the third step, **Set up the OAuth 2.0 consent screen**: - -![API Manager Credentials page: Set up the OAuth 2.0 consent screen](index/_static/GoogleConsoleAddCred.png) - -* Enter your public facing **Email address** and the **Product name** shown for your app when Google+ prompts the user to sign in. Additional options are available under **More customization options**. - -* Tap **Continue** to proceed to the last step, **Download credentials**: - -![API Manager Credentials page: Download credentials](index/_static/GoogleConsoleFinish.png) - -* Tap **Download** to save a JSON file with application secrets, and **Done** to complete creation of the new app. - -* When deploying the site you'll need to revisit the **Google Console** and register a new public url. +* Navigate to [Integrating Google Sign-In into your web app](https://developers.google.com/identity/sign-in/web/devconsole-project) and select **CONFIGURE A PROJECT**. +* In the **Configure your OAuth client** dialog, select **Web server**. +* In the **Authorized redirect URIs** text entry box, set the redirect URI. For example, `https://localhost:5001/signin-google` +* Save the **Client ID** and **Client Secret**. +* When deploying the site, register the new public url from the **Google Console**. ## Store Google ClientID and ClientSecret -Link sensitive settings like Google `Client ID` and `Client Secret` to your application configuration using the [Secret Manager](xref:security/app-secrets). For the purposes of this tutorial, name the tokens `Authentication:Google:ClientId` and `Authentication:Google:ClientSecret`. - -The values for these tokens can be found in the JSON file downloaded in the previous step under `web.client_id` and `web.client_secret`. - -## Configure Google Authentication - -::: moniker range=">= aspnetcore-2.0" - -Add the Google service in the `ConfigureServices` method in *Startup.cs* file: - -```csharp -services.AddDefaultIdentity() - .AddDefaultUI(UIFramework.Bootstrap4) - .AddEntityFrameworkStores(); +Store sensitive settings such as the Google `Client ID` and `Client Secret` with the [Secret Manager](xref:security/app-secrets). For the purposes of this tutorial, name the tokens `Authentication:Google:ClientId` and `Authentication:Google:ClientSecret`: -services.AddAuthentication().AddGoogle(googleOptions => -{ - googleOptions.ClientId = Configuration["Authentication:Google:ClientId"]; - googleOptions.ClientSecret = Configuration["Authentication:Google:ClientSecret"]; -}); +```console +dotnet user-secrets set "Authentication:Google:ClientId" "X.apps.googleusercontent.com" +dotnet user-secrets set "Authentication:Google:ClientSecret" "" ``` -[!INCLUDE [default settings configuration](includes/default-settings.md)] - -[!INCLUDE[](includes/chain-auth-providers.md)] - -::: moniker-end - -::: moniker range="< aspnetcore-2.0" - -The project template used in this tutorial ensures that [Microsoft.AspNetCore.Authentication.Google](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.Google) package is installed. - -* To install this package with Visual Studio 2017, right-click on the project and select **Manage NuGet Packages**. -* To install with .NET Core CLI, execute the following in your project directory: +You can manage your API credentials and usage in the [API Console](https://console.developers.google.com/apis/dashboard). -`dotnet add package Microsoft.AspNetCore.Authentication.Google` +## Configure Google authentication -Add the Google middleware in the `Configure` method in *Startup.cs* file: +Add the Google service to `Startup.ConfigureServices`. -```csharp -app.UseGoogleAuthentication(new GoogleOptions() -{ - ClientId = Configuration["Authentication:Google:ClientId"], - ClientSecret = Configuration["Authentication:Google:ClientSecret"] -}); -``` - -::: moniker-end - -See the [GoogleOptions](/dotnet/api/microsoft.aspnetcore.builder.googleoptions) API reference for more information on configuration options supported by Google authentication. This can be used to request different information about the user. +[!INCLUDE [default settings configuration](includes/default-settings2-2.md)] ## Sign in with Google -Run your application and click **Log in**. An option to sign in with Google appears: - -![Web application running in Microsoft Edge: User not authenticated](index/_static/DoneGoogle.png) - -When you click on Google, you are redirected to Google for authentication: +* Run the app and click **Log in**. An option to sign in with Google appears. +* Click the **Google** button, which redirects to Google for authentication. +* After entering your Google credentials, you are redirected back to the web site. -![Google authentication dialog](index/_static/GoogleLogin.png) +[!INCLUDE[Forward request information when behind a proxy or load balancer section](includes/forwarded-headers-middleware.md)] -After entering your Google credentials, then you are redirected back to the web site where you can set your email. +[!INCLUDE[](includes/chain-auth-providers.md)] -You are now logged in using your Google credentials: +See the [GoogleOptions](/dotnet/api/microsoft.aspnetcore.builder.googleoptions) API reference for more information on configuration options supported by Google authentication. This can be used to request different information about the user. -![Web application running in Microsoft Edge: User authenticated](index/_static/Done.png) +## Change the default callback URI -[!INCLUDE[Forward request information when behind a proxy or load balancer section](includes/forwarded-headers-middleware.md)] +The URI segment `/signin-google` is set as the default callback of the Google authentication provider. You can change the default callback URI while configuring the Google authentication middleware via the inherited [RemoteAuthenticationOptions.CallbackPath](/dotnet/api/microsoft.aspnetcore.authentication.remoteauthenticationoptions.callbackpath) property of the [GoogleOptions](/dotnet/api/microsoft.aspnetcore.authentication.google.googleoptions) class. ## Troubleshooting -* If you receive a `403 (Forbidden)` error page from your own app when running in development mode (or break into the debugger with the same error), ensure that **Google+ API** has been enabled in the **API Manager Library** by following the steps listed [earlier on this page](#create-the-app-in-google-api-console). If the sign in doesn't work and you aren't getting any errors, switch to development mode to make the issue easier to debug. -* **ASP.NET Core 2.x only:** If Identity isn't configured by calling `services.AddIdentity` in `ConfigureServices`, attempting to authenticate will result in *ArgumentException: The 'SignInScheme' option must be provided*. The project template used in this tutorial ensures that this is done. -* If the site database has not been created by applying the initial migration, you will get *A database operation failed while processing the request* error. Tap **Apply Migrations** to create the database and refresh to continue past the error. +* If the sign-in doesn't work and you aren't getting any errors, switch to development mode to make the issue easier to debug. +* If Identity isn't configured by calling `services.AddIdentity` in `ConfigureServices`, attempting to authenticate results in *ArgumentException: The 'SignInScheme' option must be provided*. The project template used in this tutorial ensures that this is done. +* If the site database has not been created by applying the initial migration, you get *A database operation failed while processing the request* error. Tap **Apply Migrations** to create the database and refresh to continue past the error. ## Next steps * This article showed how you can authenticate with Google. You can follow a similar approach to authenticate with other providers listed on the [previous page](xref:security/authentication/social/index). - -* Once you publish your web site to Azure web app, you should reset the `ClientSecret` in the Google API Console. - +* Once you publish the app to Azure, reset the `ClientSecret` in the Google API Console. * Set the `Authentication:Google:ClientId` and `Authentication:Google:ClientSecret` as application settings in the Azure portal. The configuration system is set up to read keys from environment variables. diff --git a/aspnetcore/security/authentication/social/includes/default-settings.md b/aspnetcore/security/authentication/social/includes/default-settings.md index 2a9f794e3166..a19c40256a28 100644 --- a/aspnetcore/security/authentication/social/includes/default-settings.md +++ b/aspnetcore/security/authentication/social/includes/default-settings.md @@ -1,3 +1,4 @@ -The call to [AddIdentity](/dotnet/api/microsoft.extensions.dependencyinjection.identityservicecollectionextensions.addidentity) configures the default scheme settings. The [AddAuthentication(String)](/dotnet/api/microsoft.extensions.dependencyinjection.authenticationservicecollectionextensions.addauthentication#Microsoft_Extensions_DependencyInjection_AuthenticationServiceCollectionExtensions_AddAuthentication_Microsoft_Extensions_DependencyInjection_IServiceCollection_System_String_) overload sets the [DefaultScheme](/dotnet/api/microsoft.aspnetcore.authentication.authenticationoptions.defaultscheme) property. The [AddAuthentication(Action<AuthenticationOptions>)](/dotnet/api/microsoft.extensions.dependencyinjection.authenticationservicecollectionextensions.addauthentication#Microsoft_Extensions_DependencyInjection_AuthenticationServiceCollectionExtensions_AddAuthentication_Microsoft_Extensions_DependencyInjection_IServiceCollection_System_Action_Microsoft_AspNetCore_Authentication_AuthenticationOptions__) overload allows configuring authentication options, which can be used to set up default authentication schemes for different purposes. Subsequent calls to `AddAuthentication` override previously configured [AuthenticationOptions](/dotnet/api/microsoft.aspnetcore.builder.authenticationoptions) properties. + +The call to [AddIdentity](/dotnet/api/microsoft.extensions.dependencyinjection.identityservicecollectionuiextensions.adddefaultidentity) configures the default scheme settings. The [AddAuthentication(String)](/dotnet/api/microsoft.extensions.dependencyinjection.authenticationservicecollectionextensions.addauthentication#Microsoft_Extensions_DependencyInjection_AuthenticationServiceCollectionExtensions_AddAuthentication_Microsoft_Extensions_DependencyInjection_IServiceCollection_System_String_) overload sets the [DefaultScheme](/dotnet/api/microsoft.aspnetcore.authentication.authenticationoptions.defaultscheme) property. The [AddAuthentication(Action<AuthenticationOptions>)](/dotnet/api/microsoft.extensions.dependencyinjection.authenticationservicecollectionextensions.addauthentication#Microsoft_Extensions_DependencyInjection_AuthenticationServiceCollectionExtensions_AddAuthentication_Microsoft_Extensions_DependencyInjection_IServiceCollection_System_Action_Microsoft_AspNetCore_Authentication_AuthenticationOptions__) overload allows configuring authentication options, which can be used to set up default authentication schemes for different purposes. Subsequent calls to `AddAuthentication` override previously configured [AuthenticationOptions](/dotnet/api/microsoft.aspnetcore.builder.authenticationoptions) properties. [AuthenticationBuilder](/dotnet/api/microsoft.aspnetcore.authentication.authenticationbuilder) extension methods that register an authentication handler may only be called once per authentication scheme. Overloads exist that allow configuring the scheme properties, scheme name, and display name. diff --git a/aspnetcore/security/authentication/social/includes/default-settings2-2.md b/aspnetcore/security/authentication/social/includes/default-settings2-2.md new file mode 100644 index 000000000000..2a9f794e3166 --- /dev/null +++ b/aspnetcore/security/authentication/social/includes/default-settings2-2.md @@ -0,0 +1,3 @@ +The call to [AddIdentity](/dotnet/api/microsoft.extensions.dependencyinjection.identityservicecollectionextensions.addidentity) configures the default scheme settings. The [AddAuthentication(String)](/dotnet/api/microsoft.extensions.dependencyinjection.authenticationservicecollectionextensions.addauthentication#Microsoft_Extensions_DependencyInjection_AuthenticationServiceCollectionExtensions_AddAuthentication_Microsoft_Extensions_DependencyInjection_IServiceCollection_System_String_) overload sets the [DefaultScheme](/dotnet/api/microsoft.aspnetcore.authentication.authenticationoptions.defaultscheme) property. The [AddAuthentication(Action<AuthenticationOptions>)](/dotnet/api/microsoft.extensions.dependencyinjection.authenticationservicecollectionextensions.addauthentication#Microsoft_Extensions_DependencyInjection_AuthenticationServiceCollectionExtensions_AddAuthentication_Microsoft_Extensions_DependencyInjection_IServiceCollection_System_Action_Microsoft_AspNetCore_Authentication_AuthenticationOptions__) overload allows configuring authentication options, which can be used to set up default authentication schemes for different purposes. Subsequent calls to `AddAuthentication` override previously configured [AuthenticationOptions](/dotnet/api/microsoft.aspnetcore.builder.authenticationoptions) properties. + +[AuthenticationBuilder](/dotnet/api/microsoft.aspnetcore.authentication.authenticationbuilder) extension methods that register an authentication handler may only be called once per authentication scheme. Overloads exist that allow configuring the scheme properties, scheme name, and display name. diff --git a/aspnetcore/security/authentication/windowsauth/sample_snapshot/web_2.config b/aspnetcore/security/authentication/windowsauth/sample_snapshot/web_2.config index 8345481eedfe..bb8537e45504 100644 --- a/aspnetcore/security/authentication/windowsauth/sample_snapshot/web_2.config +++ b/aspnetcore/security/authentication/windowsauth/sample_snapshot/web_2.config @@ -6,8 +6,8 @@ - - + +
diff --git a/aspnetcore/security/authorization/iauthorizationpolicyprovider.md b/aspnetcore/security/authorization/iauthorizationpolicyprovider.md index ff99825aca7f..838feb5a4927 100644 --- a/aspnetcore/security/authorization/iauthorizationpolicyprovider.md +++ b/aspnetcore/security/authorization/iauthorizationpolicyprovider.md @@ -4,7 +4,7 @@ author: mjrousos description: Learn how to use a custom IAuthorizationPolicyProvider in an ASP.NET Core app to dynamically generate authorization policies. ms.author: riande ms.custom: mvc -ms.date: 05/02/2018 +ms.date: 01/21/2019 uid: security/authorization/iauthorizationpolicyprovider --- # Custom Authorization Policy Providers using IAuthorizationPolicyProvider in ASP.NET Core @@ -19,8 +19,7 @@ Examples of scenarios where a custom [IAuthorizationPolicyProvider](/dotnet/api/ * Using a large range of policies (for different room numbers or ages, for example), so it doesn’t make sense to add each individual authorization policy with an `AuthorizationOptions.AddPolicy` call. * Creating policies at runtime based on information in an external data source (like a database) or determining authorization requirements dynamically through another mechanism. -[View or download sample code](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/AuthSamples/) from the [AspNetCore GitHub repository](https://github.com/aspnet/AspNetCore). Download the aspnet/AuthSamples repository ZIP file. -Unzip the *AuthSamples-master.zip* file. Navigate to the *samples/CustomPolicyProvider* project folder. +[View or download sample code](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/CustomPolicyProvider) from the [AspNetCore GitHub repository](https://github.com/aspnet/AspNetCore). Download the aspnet/AspNetCore repository ZIP file. Unzip the file. Navigate to the *src/Security/samples/CustomPolicyProvider* project folder. ## Customize policy retrieval @@ -149,4 +148,4 @@ To use custom policies from an `IAuthorizationPolicyProvider`, you must: services.AddSingleton(); ``` -A complete custom `IAuthorizationPolicyProvider` sample is available in the [aspnet/AuthSamples GitHub repository](https://github.com/aspnet/AuthSamples/tree/master/samples/CustomPolicyProvider). +A complete custom `IAuthorizationPolicyProvider` sample is available in the [aspnet/AuthSamples GitHub repository](https://github.com/aspnet/AspNetCore/tree/release/2.2/src/Security/samples/CustomPolicyProvider). diff --git a/aspnetcore/security/data-protection/configuration/overview.md b/aspnetcore/security/data-protection/configuration/overview.md index f15a3fceb197..4e174f15c63e 100644 --- a/aspnetcore/security/data-protection/configuration/overview.md +++ b/aspnetcore/security/data-protection/configuration/overview.md @@ -129,7 +129,7 @@ public void ConfigureServices(IServiceCollection services) ## SetApplicationName -By default, the Data Protection system isolates apps from one another, even if they're sharing the same physical key repository. This prevents the apps from understanding each other's protected payloads. +By default, the Data Protection system isolates apps from one another based on their content root paths, even if they're sharing the same physical key repository. This prevents the apps from understanding each other's protected payloads. To share protected payloads among apps: diff --git a/aspnetcore/security/data-protection/extensibility/key-management/samples/key-management-extensibility.cs b/aspnetcore/security/data-protection/extensibility/key-management/samples/key-management-extensibility.cs index 09a6dbcf4360..ef05b3f2016a 100644 --- a/aspnetcore/security/data-protection/extensibility/key-management/samples/key-management-extensibility.cs +++ b/aspnetcore/security/data-protection/extensibility/key-management/samples/key-management-extensibility.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.DataProtection.KeyManagement; using Microsoft.AspNetCore.DataProtection.XmlEncryption; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; public class Program { @@ -40,7 +41,7 @@ public MyKeyEscrowSink(IServiceProvider services) _escrowEncryptor = new DpapiNGXmlEncryptor( "SID=S-1-5-21-1004336348-1177238915-682003330-512", DpapiNGProtectionDescriptorFlags.None, - services); + new LoggerFactory()); } public void Store(Guid keyId, XElement element) diff --git a/aspnetcore/security/gdpr.md b/aspnetcore/security/gdpr.md index 758d6948e75b..0173b665a170 100644 --- a/aspnetcore/security/gdpr.md +++ b/aspnetcore/security/gdpr.md @@ -86,6 +86,7 @@ Notes: * To generate the `Account/Manage` code, see [Scaffold Identity](xref:security/authentication/scaffold-identity). * The **Delete** and **Download** links only act on the default identity data. Apps that create custom user data must be extended to delete/download the custom user data. For more information, see [Add, download, and delete custom user data to Identity](xref:security/authentication/add-user-data). * Saved tokens for the user that are stored in the Identity database table `AspNetUserTokens` are deleted when the user is deleted via the cascading delete behavior due to the [foreign key](https://github.com/aspnet/Identity/blob/release/2.1/src/EF/IdentityUserContext.cs#L152). +* [External provider authentication](xref:security/authentication/social/index), such as Facebook and Google, isn't available before the cookie policy is accepted. ## Encryption at rest diff --git a/aspnetcore/signalr/authn-and-authz.md b/aspnetcore/signalr/authn-and-authz.md index 2d359d135d95..d2d612918b5b 100644 --- a/aspnetcore/signalr/authn-and-authz.md +++ b/aspnetcore/signalr/authn-and-authz.md @@ -1,6 +1,6 @@ --- title: Authentication and authorization in ASP.NET Core SignalR -author: tdykstra +author: bradygaster description: Learn how to use authentication and authorization in ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' ms.author: anurse diff --git a/aspnetcore/signalr/configuration.md b/aspnetcore/signalr/configuration.md index e5df4c8f5b85..7f5a9dda7304 100644 --- a/aspnetcore/signalr/configuration.md +++ b/aspnetcore/signalr/configuration.md @@ -1,9 +1,9 @@ --- title: ASP.NET Core SignalR configuration -author: tdykstra +author: bradygaster description: Learn how to configure ASP.NET Core SignalR apps. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 09/06/2018 uid: signalr/configuration @@ -57,6 +57,7 @@ The following table describes options for configuring SignalR hubs: | Option | Default Value | Description | | ------ | ------------- | ----------- | +| `ClientTimeoutInterval` | 30 seconds | The server will consider the client disconnected if it hasn't received a message (including keep-alive) in this interval. It is possible for it to take longer than this timeout interval for the client to actually be marked disconnected, due to how this is implemented. The recommended value is double the `KeepAliveInterval` value.| | `HandshakeTimeout` | 15 seconds | If the client doesn't send an initial handshake message within this time interval, the connection is closed. This is an advanced setting that should only be modified if handshake timeout errors are occurring due to severe network latency. For more detail on the handshake process, see the [SignalR Hub Protocol Specification](https://github.com/aspnet/SignalR/blob/master/specs/HubProtocol.md). | | `KeepAliveInterval` | 15 seconds | If the server hasn't sent a message within this interval, a ping message is sent automatically to keep the connection open. When changing `KeepAliveInterval`, change the `ServerTimeout`/`serverTimeoutInMilliseconds` setting on the client. The recommended `ServerTimeout`/`serverTimeoutInMilliseconds` value is double the `KeepAliveInterval` value. | | `SupportedProtocols` | All installed protocols | Protocols supported by this hub. By default, all protocols registered on the server are allowed, but protocols can be removed from this list to disable specific protocols for individual hubs. | diff --git a/aspnetcore/signalr/dotnet-client.md b/aspnetcore/signalr/dotnet-client.md index be07ced6bdba..3eadf6e8e6d0 100644 --- a/aspnetcore/signalr/dotnet-client.md +++ b/aspnetcore/signalr/dotnet-client.md @@ -1,9 +1,9 @@ --- title: ASP.NET Core SignalR .NET Client -author: tdykstra +author: bradygaster description: Information about the ASP.NET Core SignalR .NET Client monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 09/10/2018 uid: signalr/dotnet-client diff --git a/aspnetcore/signalr/groups.md b/aspnetcore/signalr/groups.md index 73b000c60fec..fffc6721cab8 100644 --- a/aspnetcore/signalr/groups.md +++ b/aspnetcore/signalr/groups.md @@ -1,9 +1,9 @@ --- title: Manage users and groups in SignalR -author: tdykstra +author: bradygaster description: Overview of ASP.NET Core SignalR User and Group management. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 06/04/2018 uid: signalr/groups diff --git a/aspnetcore/signalr/hubcontext.md b/aspnetcore/signalr/hubcontext.md index 54cee61b2e3c..80a41b591f01 100644 --- a/aspnetcore/signalr/hubcontext.md +++ b/aspnetcore/signalr/hubcontext.md @@ -1,9 +1,9 @@ --- title: SignalR HubContext -author: tdykstra +author: bradygaster description: Learn how to use the ASP.NET Core SignalR HubContext service for sending notifications to clients from outside a hub. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/01/2018 uid: signalr/hubcontext diff --git a/aspnetcore/signalr/hubs.md b/aspnetcore/signalr/hubs.md index d6b8cb0a9b06..cfe08d191923 100644 --- a/aspnetcore/signalr/hubs.md +++ b/aspnetcore/signalr/hubs.md @@ -1,9 +1,9 @@ --- title: Use hubs in ASP.NET Core SignalR -author: tdykstra +author: bradygaster description: Learn how to use hubs in ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/20/2018 uid: signalr/hubs diff --git a/aspnetcore/signalr/introduction.md b/aspnetcore/signalr/introduction.md index 5434848d4426..91612027062a 100644 --- a/aspnetcore/signalr/introduction.md +++ b/aspnetcore/signalr/introduction.md @@ -1,9 +1,9 @@ --- title: Introduction to ASP.NET Core SignalR -author: tdykstra +author: bradygaster description: Learn how the ASP.NET Core SignalR library simplifies adding real-time functionality to apps. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 04/25/2018 uid: signalr/introduction diff --git a/aspnetcore/signalr/javascript-client.md b/aspnetcore/signalr/javascript-client.md index e55579dc55c3..96bd61ff1342 100644 --- a/aspnetcore/signalr/javascript-client.md +++ b/aspnetcore/signalr/javascript-client.md @@ -1,9 +1,9 @@ --- title: ASP.NET Core SignalR JavaScript client -author: tdykstra +author: bradygaster description: Overview of ASP.NET Core SignalR JavaScript client. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/14/2018 uid: signalr/javascript-client diff --git a/aspnetcore/signalr/messagepackhubprotocol.md b/aspnetcore/signalr/messagepackhubprotocol.md index 8fb2269b6c46..e5138fe53678 100644 --- a/aspnetcore/signalr/messagepackhubprotocol.md +++ b/aspnetcore/signalr/messagepackhubprotocol.md @@ -1,9 +1,9 @@ --- title: Use MessagePack Hub Protocol in SignalR for ASP.NET Core -author: tdykstra +author: bradygaster description: Add MessagePack Hub Protocol to ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 06/04/2018 uid: signalr/messagepackhubprotocol diff --git a/aspnetcore/signalr/publish-to-azure-web-app.md b/aspnetcore/signalr/publish-to-azure-web-app.md index 13eac467da63..2b94f83a47e1 100644 --- a/aspnetcore/signalr/publish-to-azure-web-app.md +++ b/aspnetcore/signalr/publish-to-azure-web-app.md @@ -1,9 +1,9 @@ --- title: Publish an ASP.NET Core SignalR app to Azure Web App -author: tdykstra +author: bradygaster description: Publish an ASP.NET Core SignalR app to Azure Web App monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 04/20/2018 uid: signalr/publish-to-azure-web-app diff --git a/aspnetcore/signalr/redis-backplane.md b/aspnetcore/signalr/redis-backplane.md index 3837407e171e..3121d36abca6 100644 --- a/aspnetcore/signalr/redis-backplane.md +++ b/aspnetcore/signalr/redis-backplane.md @@ -1,9 +1,9 @@ --- title: Redis backplane for ASP.NET Core SignalR scale-out -author: tdykstra +author: bradygaster description: Learn how to set up a Redis backplane to enable scale-out for an ASP.NET Core SignalR app. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/28/2018 uid: signalr/redis-backplane diff --git a/aspnetcore/signalr/scale.md b/aspnetcore/signalr/scale.md index 7ed011866ba9..30f59f5c02fd 100644 --- a/aspnetcore/signalr/scale.md +++ b/aspnetcore/signalr/scale.md @@ -1,9 +1,9 @@ --- title: ASP.NET Core SignalR production hosting and scaling -author: tdykstra +author: bradygaster description: Learn how to avoid performance and scaling problems in apps that use ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/28/2018 uid: signalr/scale diff --git a/aspnetcore/signalr/security.md b/aspnetcore/signalr/security.md index e975715aced7..e6196f9a22b2 100644 --- a/aspnetcore/signalr/security.md +++ b/aspnetcore/signalr/security.md @@ -1,6 +1,6 @@ --- title: Security considerations in ASP.NET Core SignalR -author: tdykstra +author: bradygaster description: Learn how to use authentication and authorization in ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' ms.author: anurse diff --git a/aspnetcore/signalr/streaming.md b/aspnetcore/signalr/streaming.md index 58e266ca10e2..6722abfb6e60 100644 --- a/aspnetcore/signalr/streaming.md +++ b/aspnetcore/signalr/streaming.md @@ -1,9 +1,9 @@ --- title: Use streaming in ASP.NET Core SignalR -author: tdykstra +author: bradygaster description: monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/14/2018 uid: signalr/streaming diff --git a/aspnetcore/signalr/supported-platforms.md b/aspnetcore/signalr/supported-platforms.md index 40c7694d4f42..51de9e7ef621 100644 --- a/aspnetcore/signalr/supported-platforms.md +++ b/aspnetcore/signalr/supported-platforms.md @@ -1,9 +1,9 @@ --- title: ASP.NET Core SignalR supported platforms -author: tdykstra +author: bradygaster description: Learn about the supported platforms for ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/12/2018 uid: signalr/supported-platforms diff --git a/aspnetcore/signalr/version-differences.md b/aspnetcore/signalr/version-differences.md index 81abfea91f85..e5ea257b97d2 100644 --- a/aspnetcore/signalr/version-differences.md +++ b/aspnetcore/signalr/version-differences.md @@ -1,9 +1,9 @@ --- title: Differences between SignalR and ASP.NET Core SignalR -author: tdykstra +author: bradygaster description: Differences between SignalR and ASP.NET Core SignalR monikerRange: '>= aspnetcore-2.1' -ms.author: tdykstra +ms.author: bradyg ms.date: 11/14/2018 uid: signalr/version-differences --- diff --git a/aspnetcore/toc.md b/aspnetcore/toc.md deleted file mode 100644 index 4322f5d532db..000000000000 --- a/aspnetcore/toc.md +++ /dev/null @@ -1,427 +0,0 @@ -# [ASP.NET Core documentation](/aspnet/#pivot=core) - -# Overview -## [About ASP.NET Core](xref:index) -## [Compare ASP.NET Core and ASP.NET](xref:fundamentals/choose-between-aspnet-and-aspnetcore) -## [Compare .NET Core and .NET Framework](/dotnet/articles/standard/choosing-core-framework-server) - -# [Get started](xref:getting-started) - -# What's new -## [What's new in 2.2](xref:aspnetcore-2.2) -## [What's new in 2.1](xref:aspnetcore-2.1) -## [What's new in 2.0](xref:aspnetcore-2.0) -## [What's new in 1.1](xref:aspnetcore-1.1) - -# Tutorials -## Web API apps -### [Create a web API](xref:tutorials/first-web-api) -### [Web API with MongoDB](xref:tutorials/first-mongo-app) -## Web apps -### [Razor Pages](xref:tutorials/razor-pages/index) -### [MVC](xref:tutorials/first-mvc-app/index) - -## Real-time web apps -### [SignalR with JavaScript](xref:tutorials/signalr) -### [SignalR with TypeScript](xref:tutorials/signalr-typescript-webpack) -## [Create backend services for native mobile apps](xref:mobile/native-mobile-backend) - -## Data access -### [EF Core with Razor Pages](xref:data/ef-rp/index) -### [EF Core with MVC, existing DB](/ef/core/get-started/aspnetcore/existing-db) -### [EF Core with MVC, new DB](/ef/core/get-started/aspnetcore/new-db) -### [EF Core with MVC, long tutorial](xref:data/ef-mvc/index) - -# Fundamentals -## [Overview](xref:fundamentals/index) -## [App startup](xref:fundamentals/startup) -## [Dependency injection (services)](xref:fundamentals/dependency-injection) -## [Routing](xref:fundamentals/routing) -## [Environments (dev, stage, prod)](xref:fundamentals/environments) -## [Configuration](xref:fundamentals/configuration/index) -## [Options](xref:fundamentals/configuration/options) -## [Logging](xref:fundamentals/logging/index) -## [Handle errors](xref:fundamentals/error-handling) -## Middleware -### [Overview](xref:fundamentals/middleware/index) -### [Factory-based middleware](xref:fundamentals/middleware/extensibility) -### [Factory-based middleware with third-party container](xref:fundamentals/middleware/extensibility-third-party-container) -## Host -### [Overview](xref:fundamentals/host/index) -### [Web Host](xref:fundamentals/host/web-host) -### [Generic Host](xref:fundamentals/host/generic-host) -## [Servers](xref:fundamentals/servers/index) -## [Initiate HTTP requests](xref:fundamentals/http-requests) - -# Web apps -## Razor Pages -### [Overview](xref:razor-pages/index) -### [Razor Pages tutorial](xref:tutorials/razor-pages/index) -#### [Get started](xref:tutorials/razor-pages/razor-pages-start) -#### [Add a model](xref:tutorials/razor-pages/model) -#### [Scaffolding](xref:tutorials/razor-pages/page) -#### [Work with a DB](xref:tutorials/razor-pages/sql) -#### [Update the pages](xref:tutorials/razor-pages/da1) -#### [Add search](xref:tutorials/razor-pages/search) -#### [Add a new field](xref:tutorials/razor-pages/new-field) -#### [Add validation](xref:tutorials/razor-pages/validation) - -## MVC -### [MVC Overview](xref:mvc/overview) -### [MVC tutorial](xref:tutorials/first-mvc-app/index) -#### [Get started](xref:tutorials/first-mvc-app/start-mvc) -#### [Add a controller](xref:tutorials/first-mvc-app/adding-controller) -#### [Add a view](xref:tutorials/first-mvc-app/adding-view) -#### [Add a model](xref:tutorials/first-mvc-app/adding-model) -#### [Work with a DB](xref:tutorials/first-mvc-app/working-with-sql) -#### [Controller actions and views](xref:tutorials/first-mvc-app/controller-methods-views) -#### [Add search](xref:tutorials/first-mvc-app/search) -#### [Add a new field](xref:tutorials/first-mvc-app/new-field) -#### [Add validation](xref:tutorials/first-mvc-app/validation) -#### [Examine the Details and Delete methods](xref:tutorials/first-mvc-app/details) - -### [Filters](xref:razor-pages/filter) -### [Razor Class Libraries](xref:razor-pages/ui-class) -### [Route and app conventions](xref:razor-pages/razor-pages-conventions) -### [Upload files](xref:razor-pages/upload-files) -### [Razor SDK](xref:razor-pages/sdk) - -### [Views](xref:mvc/views/overview) -### [Partial views](xref:mvc/views/partial) -### [Controllers](xref:mvc/controllers/actions) -### [Routing](xref:mvc/controllers/routing) -### [File uploads](xref:mvc/models/file-uploads) -### [Dependency injection - controllers](xref:mvc/controllers/dependency-injection) -### [Dependency injection - views](xref:mvc/views/dependency-injection) -### [Unit testing](xref:mvc/controllers/testing) -## [Session and app state](xref:fundamentals/app-state) -## Tag Helpers -### [Overview](xref:mvc/views/tag-helpers/intro) -### [Create Tag Helpers](xref:mvc/views/tag-helpers/authoring) -### [Use Tag Helpers in forms](xref:mvc/views/working-with-forms) -### [Tag Helper Components](xref:mvc/views/tag-helpers/th-components) -### Built-in Tag Helpers -#### [Anchor](xref:mvc/views/tag-helpers/builtin-th/anchor-tag-helper) -#### [Cache](xref:mvc/views/tag-helpers/builtin-th/cache-tag-helper) -#### [Distributed Cache](xref:mvc/views/tag-helpers/builtin-th/distributed-cache-tag-helper) -#### [Environment](xref:mvc/views/tag-helpers/builtin-th/environment-tag-helper) -#### [Form](mvc/views/working-with-forms.md#the-form-tag-helper) -#### [Image](xref:mvc/views/tag-helpers/builtin-th/image-tag-helper) -#### [Input](mvc/views/working-with-forms.md#the-input-tag-helper) -#### [Label](mvc/views/working-with-forms.md#the-label-tag-helper) -#### [Partial](xref:mvc/views/tag-helpers/builtin-th/partial-tag-helper) -#### [Select](mvc/views/working-with-forms.md#the-select-tag-helper) -#### [Textarea](mvc/views/working-with-forms.md#the-textarea-tag-helper) -#### [Validation Message](mvc/views/working-with-forms.md#the-validation-message-tag-helper) -#### [Validation Summary](mvc/views/working-with-forms.md#the-validation-summary-tag-helper) -## [Layout](xref:mvc/views/layout) -## [Static files](xref:fundamentals/static-files) -## [Model binding](xref:mvc/models/model-binding) -## [Model validation](xref:mvc/models/validation) -## [Razor syntax](xref:mvc/views/razor) -## Advanced -### [View components](xref:mvc/views/view-components) -### [View compilation](xref:mvc/views/view-compilation) -### [App model](xref:mvc/controllers/application-model) -### [Filters](xref:mvc/controllers/filters) -### [Areas](xref:mvc/controllers/areas) -### [App parts](xref:mvc/extensibility/app-parts) -### [Custom model binding](xref:mvc/advanced/custom-model-binding) -### [Compatibility version](xref:mvc/compatibility-version) - -# Web API apps -## [Overview](xref:web-api/index) - -## Tutorials -### [Create a web API](xref:tutorials/first-web-api) -### [Web API with MongoDB](xref:tutorials/first-mongo-app) - -## Swagger / OpenAPI -### [Overview](xref:tutorials/web-api-help-pages-using-swagger) -### [Get started with Swashbuckle](xref:tutorials/get-started-with-swashbuckle) -### [Get started with NSwag](xref:tutorials/get-started-with-nswag) -## [Action return types](xref:web-api/action-return-types) -## [Format response data](xref:web-api/advanced/formatting) -## [Custom formatters](xref:web-api/advanced/custom-formatters) - -## [Analyzers](xref:web-api/advanced/analyzers) -## [Conventions](xref:web-api/advanced/conventions) - -# Real-time apps -## [SignalR overview](xref:signalr/introduction) -## [Supported platforms](xref:signalr/supported-platforms) -## Tutorials -### [SignalR with JavaScript](xref:tutorials/signalr) -### [SignalR with TypeScript](xref:tutorials/signalr-typescript-webpack) -## [Samples](https://github.com/aspnet/SignalR-samples) -## Server concepts -### [Hubs](xref:signalr/hubs) -### [HubContext](xref:signalr/hubcontext) -### [Users and groups](xref:signalr/groups) -### [Publish to Azure](xref:signalr/publish-to-azure-web-app) -### [API design considerations](xref:signalr/api-design) -## Clients -### [.NET client](xref:signalr/dotnet-client) -### [.NET API reference](/dotnet/api/microsoft.aspnetcore.signalr.client) -### [Java client](xref:signalr/java-client) -### [Java API reference](/java/api/com.microsoft.signalr?view=aspnet-signalr-java) -### [JavaScript client](xref:signalr/javascript-client) -### [JavaScript API reference](/javascript/api/?view=signalr-js-latest) -## Hosting and scaling -### [Overview](xref:signalr/scale) -### [Azure SignalR Service](/azure/azure-signalr/signalr-overview) -### [Redis backplane](xref:signalr/redis-backplane) -## [Configuration](xref:signalr/configuration) -## [Authentication and authorization](xref:signalr/authn-and-authz) -## [Security considerations](xref:signalr/security) -## [MessagePack Hub Protocol](xref:signalr/messagepackhubprotocol) -## [Streaming](xref:signalr/streaming) -## [Compare SignalR and SignalR Core](xref:signalr/version-differences) -## [WebSockets without SignalR](xref:fundamentals/websockets) - -# Test, debug, and troubleshoot -## [Unit testing](/dotnet/articles/core/testing/unit-testing-with-dotnet-test) -## [Razor Pages unit tests](xref:test/razor-pages-tests) -## [Test controllers](xref:mvc/controllers/testing) -## [Remote debugging](/visualstudio/debugger/remote-debugging-azure) -## [Snapshot debugging](/azure/application-insights/app-insights-snapshot-debugger) -## [Snapshot debugging in Visual Studio](/visualstudio/debugger/debug-live-azure-applications) -## [Integration tests](xref:test/integration-tests) -## [Load and stress testing](xref:test/loadtests) -## [Troubleshoot](xref:test/troubleshoot) -## [Logging](xref:fundamentals/logging/index) - -# Data access -## Tutorials -### EF Core with Razor Pages -#### [Overview](xref:data/ef-rp/index) -#### [Get started](xref:data/ef-rp/intro) -#### [Create, Read, Update, and Delete](xref:data/ef-rp/crud) -#### [Sort, filter, page, and group](xref:data/ef-rp/sort-filter-page) -#### [Migrations](xref:data/ef-rp/migrations) -#### [Create a complex data model](xref:data/ef-rp/complex-data-model) -#### [Read related data](xref:data/ef-rp/read-related-data) -#### [Update related data](xref:data/ef-rp/update-related-data) -#### [Handle concurrency conflicts](xref:data/ef-rp/concurrency) -### [EF Core with MVC, new DB](/ef/core/get-started/aspnetcore/new-db) -### [EF Core with MVC, existing DB](/ef/core/get-started/aspnetcore/existing-db) -### EF Core with MVC, long tutorial -#### [Overview](xref:data/ef-mvc/index) -#### [Get started](xref:data/ef-mvc/intro) -#### [Create, Read, Update, and Delete](xref:data/ef-mvc/crud) -#### [Sort, filter, page, and group](xref:data/ef-mvc/sort-filter-page) -#### [Migrations](xref:data/ef-mvc/migrations) -#### [Create a complex data model](xref:data/ef-mvc/complex-data-model) -#### [Read related data](xref:data/ef-mvc/read-related-data) -#### [Update related data](xref:data/ef-mvc/update-related-data) -#### [Handle concurrency conflicts](xref:data/ef-mvc/concurrency) -#### [Inheritance](xref:data/ef-mvc/inheritance) -#### [Advanced topics](xref:data/ef-mvc/advanced) -## [EF 6 with ASP.NET Core](xref:data/entity-framework-6) -## Azure Storage with Visual Studio -### [Connected Services](/azure/vs-azure-tools-connected-services-storage) -### [Blob storage](/azure/vs-storage-aspnet5-getting-started-blobs/) -### [Queue storage](/azure/vs-storage-aspnet5-getting-started-queues/) -### [Table storage](/azure/vs-storage-aspnet5-getting-started-tables/) - -# Client-side development -## [Overview](xref:client-side/index) -## [Gulp](xref:client-side/using-gulp) -## [Grunt](xref:client-side/using-grunt) -## LibMan -### [Overview](xref:client-side/libman/index) -### [CLI](xref:client-side/libman/libman-cli) -### [Visual Studio](xref:client-side/libman/libman-vs) -## [Bower](xref:client-side/bower) -## [LESS, Sass, and Font Awesome](xref:client-side/less-sass-fa) -## [Bundle and minify](xref:client-side/bundling-and-minification) -## [Browser Link](xref:client-side/using-browserlink) -## Single Page Apps -### [Overview](xref:spa/index) -### [Angular](xref:spa/angular) -### [React](xref:spa/react) -### [React with Redux](xref:spa/react-with-redux) -### [JavaScriptServices](xref:client-side/spa-services) - -# Hosting and deployment -## [Overview](xref:host-and-deploy/index) -## Host on Azure App Service -### [Overview](xref:host-and-deploy/azure-apps/index) -### [Publish with Visual Studio](xref:tutorials/publish-to-azure-webapp-using-vs) -### [Publish with CLI tools](/azure/app-service/app-service-web-tutorial-dotnetcore-sqldb) -### [Publish with Visual Studio and Git](xref:host-and-deploy/azure-apps/azure-continuous-deployment) -### [Continuous deployment with Azure Pipelines](/azure/devops/pipelines/get-started-yaml) -### [ASP.NET Core Module](xref:host-and-deploy/aspnet-core-module) -### [Troubleshoot](xref:host-and-deploy/azure-apps/troubleshoot) -### [Errors reference](xref:host-and-deploy/azure-iis-errors-reference) -## DevOps -### [Overview](xref:azure/devops/index) -### [Tools and downloads](xref:azure/devops/tools-and-downloads) -### [Deploy to App Service](xref:azure/devops/deploy-to-app-service) -### [Continuous integration and deployment](xref:azure/devops/cicd) -### [Monitor and troubleshoot](xref:azure/devops/monitor) -### [Next steps](xref:azure/devops/next-steps) -## Host on Windows with IIS -### [Overview](xref:host-and-deploy/iis/index) -### [ASP.NET Core Module](xref:host-and-deploy/aspnet-core-module) -### [IIS support in Visual Studio](xref:host-and-deploy/iis/development-time-iis-support) -### [IIS Modules](xref:host-and-deploy/iis/modules) -### [Troubleshoot](xref:host-and-deploy/iis/troubleshoot) -### [Errors reference](xref:host-and-deploy/azure-iis-errors-reference) -## [Kestrel](xref:fundamentals/servers/kestrel) -## [HTTP.sys](xref:fundamentals/servers/httpsys) -## [Host in a Windows service](xref:host-and-deploy/windows-service) -## [Host on Linux with Nginx](xref:host-and-deploy/linux-nginx) -## [Host on Linux with Apache](xref:host-and-deploy/linux-apache) -## Host in Docker -### [Overview](xref:host-and-deploy/docker/index) -### [Build Docker images](/dotnet/articles/core/docker/building-net-docker-images) -### [Visual Studio Tools](xref:host-and-deploy/docker/visual-studio-tools-for-docker) -### [Publish to a Docker image](/azure/vs-azure-tools-docker-hosting-web-apps-in-docker) -## [Proxy and load balancer configuration](xref:host-and-deploy/proxy-load-balancer) -## [Host in a web farm](xref:host-and-deploy/web-farm) -## [Visual Studio publish profiles](xref:host-and-deploy/visual-studio-publish-profiles) -## [Directory structure](xref:host-and-deploy/directory-structure) -## [Health checks](xref:host-and-deploy/health-checks) - -# Security and Identity -## [Overview](xref:security/index) -## Authentication -### [Introduction to Identity](xref:security/authentication/identity) -### [Scaffold Identity](xref:security/authentication/scaffold-identity) -### [Add custom user data to Identity](xref:security/authentication/add-user-data) -### [Customize Identity](xref:security/authentication/customize_identity_model) -### [Community OSS authentication options](xref:security/authentication/community) -### [Configure Identity](xref:security/authentication/identity-configuration) -### [Configure Windows Authentication](xref:security/authentication/windowsauth) -### [Custom storage providers for Identity](xref:security/authentication/identity-custom-storage-providers) -### External providers -#### [Overview](xref:security/authentication/social/index) -#### [Facebook authentication](xref:security/authentication/facebook-logins) -#### [Twitter authentication](xref:security/authentication/twitter-logins) -#### [Google authentication](xref:security/authentication/google-logins) -#### [Microsoft authentication](xref:security/authentication/microsoft-logins) -#### [External authentication providers](xref:security/authentication/otherlogins) -#### [Additional claims](xref:security/authentication/social/additional-claims) -### [WS-Federation authentication](xref:security/authentication/ws-federation) -### [Account confirmation and password recovery](xref:security/authentication/accconfirm) -### [Enable QR code generation in Identity](xref:security/authentication/identity-enable-qrcodes) -### [Two-factor authentication with SMS](xref:security/authentication/2fa) -### [Use Cookie Authentication without Identity](xref:security/authentication/cookie) -### Azure Active Directory -#### [Overview](xref:security/authentication/azure-active-directory/index) -#### [Integrate Azure AD into a web app](https://azure.microsoft.com/documentation/samples/active-directory-dotnet-webapp-openidconnect-aspnetcore/) -#### [Integrate Azure AD B2C into a web app](xref:security/authentication/azure-ad-b2c) -#### [Integrate Azure AD B2C into a web API](xref:security/authentication/azure-ad-b2c-webapi) -#### [Call a web API from WPF](https://azure.microsoft.com/documentation/samples/active-directory-dotnet-native-aspnetcore/) -#### [Call a web API in a web app using Azure AD](https://azure.microsoft.com/documentation/samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/) -### [Secure ASP.NET Core apps with IdentityServer4](https://identityserver4.readthedocs.io/) -### [Secure ASP.NET Core apps with Azure App Service authentication (Easy Auth)](/azure/app-service/app-service-authentication-overview) -### [Individual user accounts](xref:security/authentication/individual) -## Authorization -### [Overview](xref:security/authorization/introduction) -### [Create a web app with authorization](xref:security/authorization/secure-data) -### [Razor Pages authorization conventions](xref:security/authorization/razor-pages-authorization) -### [Simple authorization](xref:security/authorization/simple) -### [Role-based authorization](xref:security/authorization/roles) -### [Claims-based authorization](xref:security/authorization/claims) -### [Policy-based authorization](xref:security/authorization/policies) -### [Authorization policy providers](xref:security/authorization/iauthorizationpolicyprovider) -### [Dependency injection in requirement handlers](xref:security/authorization/dependencyinjection) -### [Resource-based authorization](xref:security/authorization/resourcebased) -### [View-based authorization](xref:security/authorization/views) -### [Limit identity by scheme](xref:security/authorization/limitingidentitybyscheme) -## Data protection -### [Overview](xref:security/data-protection/introduction) -### [Data Protection APIs](xref:security/data-protection/using-data-protection) -### Consumer APIs -#### [Overview](xref:security/data-protection/consumer-apis/overview) -#### [Purpose strings](xref:security/data-protection/consumer-apis/purpose-strings) -#### [Purpose hierarchy and multi-tenancy](xref:security/data-protection/consumer-apis/purpose-strings-multitenancy) -#### [Hash passwords](xref:security/data-protection/consumer-apis/password-hashing) -#### [Limit the lifetime of protected payloads](xref:security/data-protection/consumer-apis/limited-lifetime-payloads) -#### [Unprotect payloads whose keys have been revoked](xref:security/data-protection/consumer-apis/dangerous-unprotect) -### Configuration -#### [Overview](xref:security/data-protection/configuration/index) -#### [Configure data protection](xref:security/data-protection/configuration/overview) -#### [Default settings](xref:security/data-protection/configuration/default-settings) -#### [Machine-wide policy](xref:security/data-protection/configuration/machine-wide-policy) -#### [Non-DI aware scenarios](xref:security/data-protection/configuration/non-di-scenarios) -### Extensibility APIs -#### [Overview](xref:security/data-protection/extensibility/index) -#### [Core cryptography extensibility](xref:security/data-protection/extensibility/core-crypto) -#### [Key management extensibility](xref:security/data-protection/extensibility/key-management) -#### [Miscellaneous APIs](xref:security/data-protection/extensibility/misc-apis) -### Implementation -#### [Overview](xref:security/data-protection/implementation/index) -#### [Authenticated encryption details](xref:security/data-protection/implementation/authenticated-encryption-details) -#### [Subkey derivation and authenticated encryption](xref:security/data-protection/implementation/subkeyderivation) -#### [Context headers](xref:security/data-protection/implementation/context-headers) -#### [Key management](xref:security/data-protection/implementation/key-management) -#### [Key storage providers](xref:security/data-protection/implementation/key-storage-providers) -#### [Key encryption at rest](xref:security/data-protection/implementation/key-encryption-at-rest) -#### [Key immutability and settings](xref:security/data-protection/implementation/key-immutability) -#### [Key storage format](xref:security/data-protection/implementation/key-storage-format) -#### [Ephemeral data protection providers](xref:security/data-protection/implementation/key-storage-ephemeral) -### Compatibility -#### [Overview](xref:security/data-protection/compatibility/index) -#### [Replace in ASP.NET](xref:security/data-protection/compatibility/replacing-machinekey) -## [Protect secrets in development](xref:security/app-secrets) -## [Enforce HTTPS](xref:security/enforcing-ssl) -## [EU General Data Protection Regulation (GDPR) support](xref:security/gdpr) -## [Azure Key Vault configuration provider](xref:security/key-vault-configuration) -## [Anti-request forgery](xref:security/anti-request-forgery) -## [Prevent open redirect attacks](xref:security/preventing-open-redirects) -## [Prevent Cross-Site Scripting](xref:security/cross-site-scripting) -## [Enable Cross-Origin Requests (CORS)](xref:security/cors) -## [Share cookies among apps](xref:security/cookie-sharing) -## [IP safelist](xref:security/ip-safelist) - -# Performance -## [Overview](xref:performance/performance-best-practices) -## Response caching -### [Overview](xref:performance/caching/response) -### [In-memory cache](xref:performance/caching/memory) -### [Distributed caching](xref:performance/caching/distributed) -### [Response caching middleware](xref:performance/caching/middleware) -## [Response compression](xref:performance/response-compression) -## [Diagnostic Tools](xref:performance/diagnostic-tools) -## [Load and stress testing](xref:test/loadtests) - -# Other topics -## [Globalization and localization](xref:fundamentals/localization) -## [Portable Object localization with Orchard Core](xref:fundamentals/portable-object-localization) -## [URL rewriting](xref:fundamentals/url-rewriting) -## [File Providers](xref:fundamentals/file-providers) -## [Request Features](xref:fundamentals/request-features) -## [Access HttpContext](xref:fundamentals/httpcontext) -## [Change tokens](xref:fundamentals/change-tokens) -## [Open Web Interface for .NET (OWIN)](xref:fundamentals/owin) -## [Background tasks with hosted services](xref:fundamentals/host/hosted-services) -## [Hosting startup assemblies](xref:fundamentals/configuration/platform-specific-configuration) -## [Microsoft.AspNetCore.App metapackage](xref:fundamentals/metapackage-app) -## [Microsoft.AspNetCore.All metapackage](xref:fundamentals/metapackage) -## [Logging with LoggerMessage](xref:fundamentals/logging/loggermessage) -## [Use a file watcher](xref:tutorials/dotnet-watch) - -# Migration -## [2.2 to 3.0](xref:migration/22-to-30) -## [2.1 to 2.2](xref:migration/21-to-22) -## [2.0 to 2.1](xref:migration/20_21) -## 1.x to 2.0 -### [Overview](xref:migration/1x-to-2x/index) -### [Authentication and Identity](xref:migration/1x-to-2x/identity-2x) -## ASP.NET to ASP.NET Core -### [Overview](xref:migration/proper-to-2x/index) -### [MVC](xref:migration/mvc) -### [Web API](xref:migration/webapi) -### [Configuration](xref:migration/configuration) -### [Authentication and Identity](xref:migration/identity) -### [ClaimsPrincipal.Current](xref:migration/claimsprincipal-current) -### [Membership to Identity](xref:migration/proper-to-2x/membership-to-core-identity) -### [HTTP modules to middleware](xref:migration/http-modules) -## [Logging (not ASP.NET Core)](xref:migration/logging-nonaspnetcore) - -# [API reference](/dotnet/api/?view=aspnetcore-2.1) - -# [Contribute](https://github.com/aspnet/Docs/blob/master/CONTRIBUTING.md) diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml new file mode 100644 index 000000000000..94eb651c9d30 --- /dev/null +++ b/aspnetcore/toc.yml @@ -0,0 +1,809 @@ +- name: ASP.NET Core documentation + href: /aspnet/#pivot=core +- name: Overview + items: + - name: About ASP.NET Core + uid: index + - name: Compare ASP.NET Core and ASP.NET + uid: fundamentals/choose-between-aspnet-and-aspnetcore + - name: Compare .NET Core and .NET Framework + href: /dotnet/standard/choosing-core-framework-server +- name: Get started + uid: getting-started +- name: What's new + items: + - name: What's new in 2.2 + uid: aspnetcore-2.2 + - name: What's new in 2.1 + uid: aspnetcore-2.1 + - name: What's new in 2.0 + uid: aspnetcore-2.0 + - name: What's new in 1.1 + uid: aspnetcore-1.1 +- name: Tutorials + items: + - name: Web API apps + items: + - name: Create a web API + uid: tutorials/first-web-api + - name: Web API with MongoDB + uid: tutorials/first-mongo-app + - name: Backend for mobile + uid: mobile/native-mobile-backend + - name: Web apps + items: + - name: Razor Pages + uid: tutorials/razor-pages/index + - name: MVC + uid: tutorials/first-mvc-app/index + - name: Real-time web apps + items: + - name: SignalR with JavaScript + uid: tutorials/signalr + - name: SignalR with TypeScript + uid: tutorials/signalr-typescript-webpack + - name: Data access + items: + - name: EF Core with Razor Pages + uid: data/ef-rp/index + - name: EF Core with MVC, existing DB + href: /ef/core/get-started/aspnetcore/existing-db + - name: EF Core with MVC, new DB + href: /ef/core/get-started/aspnetcore/new-db + - name: EF Core with MVC, long tutorial + uid: data/ef-mvc/index +- name: Fundamentals + items: + - name: Overview + uid: fundamentals/index + - name: App startup + uid: fundamentals/startup + - name: Dependency injection (services) + uid: fundamentals/dependency-injection + - name: Routing + uid: fundamentals/routing + - name: Environments (dev, stage, prod) + uid: fundamentals/environments + - name: Configuration + uid: fundamentals/configuration/index + - name: Options + uid: fundamentals/configuration/options + - name: Logging + uid: fundamentals/logging/index + - name: Handle errors + uid: fundamentals/error-handling + - name: Middleware + uid: fundamentals/middleware/index + - name: Host + items: + - name: Overview + uid: fundamentals/host/index + - name: Web host + uid: fundamentals/host/web-host + - name: Generic host + uid: fundamentals/host/generic-host + - name: Servers + uid: fundamentals/servers/index + - name: Make HTTP requests + uid: fundamentals/http-requests +- name: Web apps + items: + - name: Razor Pages + items: + - name: Overview + uid: razor-pages/index + - name: Tutorial + uid: tutorials/razor-pages/index + items: + - name: Get started + uid: tutorials/razor-pages/razor-pages-start + - name: Add a model + uid: tutorials/razor-pages/model + - name: Scaffolding + uid: tutorials/razor-pages/page + - name: Work with a DB + uid: tutorials/razor-pages/sql + - name: Update the pages + uid: tutorials/razor-pages/da1 + - name: Add search + uid: tutorials/razor-pages/search + - name: Add a new field + uid: tutorials/razor-pages/new-field + - name: Add validation + uid: tutorials/razor-pages/validation + - name: Filters + uid: razor-pages/filter + - name: Razor Class Libraries + uid: razor-pages/ui-class + - name: Route and app conventions + uid: razor-pages/razor-pages-conventions + - name: Upload files + uid: razor-pages/upload-files + - name: Razor SDK + uid: razor-pages/sdk + - name: MVC + items: + - name: Overview + uid: mvc/overview + - name: Tutorial + uid: tutorials/first-mvc-app/index + items: + - name: Get started + uid: tutorials/first-mvc-app/start-mvc + - name: Add a controller + uid: tutorials/first-mvc-app/adding-controller + - name: Add a view + uid: tutorials/first-mvc-app/adding-view + - name: Add a model + uid: tutorials/first-mvc-app/adding-model + - name: Work with a DB + uid: tutorials/first-mvc-app/working-with-sql + - name: Controller actions and views + uid: tutorials/first-mvc-app/controller-methods-views + - name: Add search + uid: tutorials/first-mvc-app/search + - name: Add a new field + uid: tutorials/first-mvc-app/new-field + - name: Add validation + uid: tutorials/first-mvc-app/validation + - name: Examine the Details and Delete methods + uid: tutorials/first-mvc-app/details + - name: Views + uid: mvc/views/overview + - name: Partial views + uid: mvc/views/partial + - name: Controllers + uid: mvc/controllers/actions + - name: Routing + uid: mvc/controllers/routing + - name: File uploads + uid: mvc/models/file-uploads + - name: Dependency injection - controllers + uid: mvc/controllers/dependency-injection + - name: Dependency injection - views + uid: mvc/views/dependency-injection + - name: Unit test + uid: mvc/controllers/testing + - name: Session and app state + uid: fundamentals/app-state + - name: Tag Helpers + items: + - name: Overview + uid: mvc/views/tag-helpers/intro + - name: Create Tag Helpers + uid: mvc/views/tag-helpers/authoring + - name: Use Tag Helpers in forms + uid: mvc/views/working-with-forms + - name: Tag Helper Components + uid: mvc/views/tag-helpers/th-components + - name: Built-in Tag Helpers + items: + - name: Anchor + uid: mvc/views/tag-helpers/builtin-th/anchor-tag-helper + - name: Cache + uid: mvc/views/tag-helpers/builtin-th/cache-tag-helper + - name: Distributed Cache + uid: mvc/views/tag-helpers/builtin-th/distributed-cache-tag-helper + - name: Environment + uid: mvc/views/tag-helpers/builtin-th/environment-tag-helper + - name: Form + href: mvc/views/working-with-forms.md#the-form-tag-helper + - name: Image + uid: mvc/views/tag-helpers/builtin-th/image-tag-helper + - name: Input + href: mvc/views/working-with-forms.md#the-input-tag-helper + - name: Label + href: mvc/views/working-with-forms.md#the-label-tag-helper + - name: Partial + uid: mvc/views/tag-helpers/builtin-th/partial-tag-helper + - name: Select + href: mvc/views/working-with-forms.md#the-select-tag-helper + - name: Textarea + href: mvc/views/working-with-forms.md#the-textarea-tag-helper + - name: Validation Message + href: mvc/views/working-with-forms.md#the-validation-message-tag-helper + - name: Validation Summary + href: mvc/views/working-with-forms.md#the-validation-summary-tag-helper + - name: Layout + uid: mvc/views/layout + - name: Static files + uid: fundamentals/static-files + - name: Model binding + uid: mvc/models/model-binding + - name: Model validation + uid: mvc/models/validation + - name: Razor syntax + uid: mvc/views/razor + - name: Advanced + items: + - name: View components + uid: mvc/views/view-components + - name: View compilation + uid: mvc/views/view-compilation + - name: App model + uid: mvc/controllers/application-model + - name: Filters + uid: mvc/controllers/filters + - name: Areas + uid: mvc/controllers/areas + - name: App parts + uid: mvc/extensibility/app-parts + - name: Custom model binding + uid: mvc/advanced/custom-model-binding + - name: Compatibility version + uid: mvc/compatibility-version +- name: Web API apps + items: + - name: Overview + uid: web-api/index + - name: Tutorials + items: + - name: Create a web API + uid: tutorials/first-web-api + - name: Web API with MongoDB + uid: tutorials/first-mongo-app + - name: Swagger / OpenAPI + items: + - name: Overview + uid: tutorials/web-api-help-pages-using-swagger + - name: Get started with Swashbuckle + uid: tutorials/get-started-with-swashbuckle + - name: Get started with NSwag + uid: tutorials/get-started-with-nswag + - name: Action return types + uid: web-api/action-return-types + - name: Format response data + uid: web-api/advanced/formatting + - name: Custom formatters + uid: web-api/advanced/custom-formatters + - name: Analyzers + uid: web-api/advanced/analyzers + - name: Conventions + uid: web-api/advanced/conventions +- name: Real-time apps + items: + - name: SignalR overview + uid: signalr/introduction + - name: Supported platforms + uid: signalr/supported-platforms + - name: Tutorials + items: + - name: SignalR with JavaScript + uid: tutorials/signalr + - name: SignalR with TypeScript + uid: tutorials/signalr-typescript-webpack + - name: Samples + href: https://github.com/aspnet/SignalR-samples + - name: Server concepts + items: + - name: Hubs + uid: signalr/hubs + - name: Send from outside a hub + uid: signalr/hubcontext + - name: Users and groups + uid: signalr/groups + - name: Publish to Azure + uid: signalr/publish-to-azure-web-app + - name: API design considerations + uid: signalr/api-design + - name: Clients + items: + - name: .NET client + uid: signalr/dotnet-client + - name: .NET API reference + href: /dotnet/api/microsoft.aspnetcore.signalr.client + - name: Java client + uid: signalr/java-client + - name: Java API reference + href: /java/api/com.microsoft.signalr?view=aspnet-signalr-java + - name: JavaScript client + uid: signalr/javascript-client + - name: JavaScript API reference + href: /javascript/api/?view=signalr-js-latest + - name: Hosting and scaling + items: + - name: Overview + uid: signalr/scale + - name: Azure SignalR Service + href: /azure/azure-signalr/signalr-overview + - name: Redis backplane + uid: signalr/redis-backplane + - name: Configuration + uid: signalr/configuration + - name: Authentication and authorization + uid: signalr/authn-and-authz + - name: Security considerations + uid: signalr/security + - name: MessagePack Hub Protocol + uid: signalr/messagepackhubprotocol + - name: Streaming + uid: signalr/streaming + - name: Compare SignalR and SignalR Core + uid: signalr/version-differences + - name: WebSockets without SignalR + uid: fundamentals/websockets +- name: Test, debug, and troubleshoot + items: + - name: Unit testing + href: /dotnet/core/testing/unit-testing-with-dotnet-test + - name: Razor Pages unit tests + uid: test/razor-pages-tests + - name: Test controllers + uid: mvc/controllers/testing + - name: Remote debugging + href: /visualstudio/debugger/remote-debugging-azure + - name: Snapshot debugging + href: /azure/application-insights/app-insights-snapshot-debugger + - name: Snapshot debugging in Visual Studio + href: /visualstudio/debugger/debug-live-azure-applications + - name: Integration tests + uid: test/integration-tests + - name: Load and stress testing + uid: test/loadtests + - name: Troubleshoot + uid: test/troubleshoot + - name: Logging + uid: fundamentals/logging/index +- name: Data access + items: + - name: Tutorials + items: + - name: EF Core with Razor Pages + items: + - name: Overview + uid: data/ef-rp/index + - name: Get started + uid: data/ef-rp/intro + - name: Create, Read, Update, and Delete + uid: data/ef-rp/crud + - name: Sort, filter, page, and group + uid: data/ef-rp/sort-filter-page + - name: Migrations + uid: data/ef-rp/migrations + - name: Create a complex data model + uid: data/ef-rp/complex-data-model + - name: Read related data + uid: data/ef-rp/read-related-data + - name: Update related data + uid: data/ef-rp/update-related-data + - name: Handle concurrency conflicts + uid: data/ef-rp/concurrency + - name: EF Core with MVC, new DB + href: /ef/core/get-started/aspnetcore/new-db + - name: EF Core with MVC, existing DB + href: /ef/core/get-started/aspnetcore/existing-db + - name: EF Core with MVC, long tutorial + items: + - name: Overview + uid: data/ef-mvc/index + - name: Get started + uid: data/ef-mvc/intro + - name: Create, Read, Update, and Delete + uid: data/ef-mvc/crud + - name: Sort, filter, page, and group + uid: data/ef-mvc/sort-filter-page + - name: Migrations + uid: data/ef-mvc/migrations + - name: Create a complex data model + uid: data/ef-mvc/complex-data-model + - name: Read related data + uid: data/ef-mvc/read-related-data + - name: Update related data + uid: data/ef-mvc/update-related-data + - name: Handle concurrency conflicts + uid: data/ef-mvc/concurrency + - name: Inheritance + uid: data/ef-mvc/inheritance + - name: Advanced topics + uid: data/ef-mvc/advanced + - name: EF 6 with ASP.NET Core + uid: data/entity-framework-6 + - name: Azure Storage with Visual Studio + items: + - name: Connected Services + href: /azure/vs-azure-tools-connected-services-storage + - name: Blob storage + href: /azure/vs-storage-aspnet5-getting-started-blobs/ + - name: Queue storage + href: /azure/vs-storage-aspnet5-getting-started-queues/ + - name: Table storage + href: /azure/vs-storage-aspnet5-getting-started-tables/ +- name: Client-side development + items: + - name: Overview + uid: client-side/index + - name: Gulp + uid: client-side/using-gulp + - name: Grunt + uid: client-side/using-grunt + - name: LibMan + items: + - name: Overview + uid: client-side/libman/index + - name: CLI + uid: client-side/libman/libman-cli + - name: Visual Studio + uid: client-side/libman/libman-vs + - name: Bower + uid: client-side/bower + - name: LESS, Sass, and Font Awesome + uid: client-side/less-sass-fa + - name: Bundle and minify + uid: client-side/bundling-and-minification + - name: Browser Link + uid: client-side/using-browserlink + - name: Single Page Apps + items: + - name: Overview + uid: spa/index + - name: Angular + uid: spa/angular + - name: React + uid: spa/react + - name: React with Redux + uid: spa/react-with-redux + - name: JavaScriptServices + uid: client-side/spa-services +- name: Hosting and deployment + items: + - name: Overview + uid: host-and-deploy/index + - name: Host on Azure App Service + items: + - name: Overview + uid: host-and-deploy/azure-apps/index + - name: Publish with Visual Studio + uid: tutorials/publish-to-azure-webapp-using-vs + - name: Publish with CLI tools + href: /azure/app-service/app-service-web-tutorial-dotnetcore-sqldb + - name: Publish with Visual Studio and Git + uid: host-and-deploy/azure-apps/azure-continuous-deployment + - name: Continuous deployment with Azure Pipelines + href: /azure/devops/pipelines/get-started-yaml + - name: ASP.NET Core Module + uid: host-and-deploy/aspnet-core-module + - name: Troubleshoot + uid: host-and-deploy/azure-apps/troubleshoot + - name: Errors reference + uid: host-and-deploy/azure-iis-errors-reference + - name: DevOps + items: + - name: Overview + uid: azure/devops/index + - name: Tools and downloads + uid: azure/devops/tools-and-downloads + - name: Deploy to App Service + uid: azure/devops/deploy-to-app-service + - name: Continuous integration and deployment + uid: azure/devops/cicd + - name: Monitor and troubleshoot + uid: azure/devops/monitor + - name: Next steps + uid: azure/devops/next-steps + - name: Host on Windows with IIS + items: + - name: Overview + uid: host-and-deploy/iis/index + - name: ASP.NET Core Module + uid: host-and-deploy/aspnet-core-module + - name: IIS support in Visual Studio + uid: host-and-deploy/iis/development-time-iis-support + - name: IIS Modules + uid: host-and-deploy/iis/modules + - name: Troubleshoot + uid: host-and-deploy/iis/troubleshoot + - name: Errors reference + uid: host-and-deploy/azure-iis-errors-reference + - name: Kestrel + uid: fundamentals/servers/kestrel + - name: HTTP.sys + uid: fundamentals/servers/httpsys + - name: Host in a Windows service + uid: host-and-deploy/windows-service + - name: Host on Linux with Nginx + uid: host-and-deploy/linux-nginx + - name: Host on Linux with Apache + uid: host-and-deploy/linux-apache + - name: Host in Docker + items: + - name: Overview + uid: host-and-deploy/docker/index + - name: Build Docker images + href: /dotnet/core/docker/building-net-docker-images + - name: Visual Studio Tools + uid: host-and-deploy/docker/visual-studio-tools-for-docker + - name: Publish to a Docker image + href: /azure/vs-azure-tools-docker-hosting-web-apps-in-docker + - name: Sample Docker images + href: https://github.com/dotnet/dotnet-docker/blob/master/samples/aspnetapp/README.md + - name: Proxy and load balancer configuration + uid: host-and-deploy/proxy-load-balancer + - name: Host in a web farm + uid: host-and-deploy/web-farm + - name: Visual Studio publish profiles + uid: host-and-deploy/visual-studio-publish-profiles + - name: Directory structure + uid: host-and-deploy/directory-structure + - name: Health checks + uid: host-and-deploy/health-checks +- name: Security and Identity + items: + - name: Overview + uid: security/index + - name: Authentication + items: + - name: Introduction to Identity + uid: security/authentication/identity + - name: Scaffold Identity + uid: security/authentication/scaffold-identity + - name: Add custom user data to Identity + uid: security/authentication/add-user-data + - name: Authentication samples + uid: security/authentication/samples + - name: Customize Identity + uid: security/authentication/customize_identity_model + - name: Community OSS authentication options + uid: security/authentication/community + - name: Configure Identity + uid: security/authentication/identity-configuration + - name: Configure Windows Authentication + uid: security/authentication/windowsauth + - name: Custom storage providers for Identity + uid: security/authentication/identity-custom-storage-providers + - name: Google, Facebook ... + items: + - name: Overview + uid: security/authentication/social/index + - name: Google authentication + uid: security/authentication/google-logins + - name: Facebook authentication + uid: security/authentication/facebook-logins + - name: Microsoft authentication + uid: security/authentication/microsoft-logins + - name: Twitter authentication + uid: security/authentication/twitter-logins + - name: Other providers + uid: security/authentication/otherlogins + - name: Additional claims + uid: security/authentication/social/additional-claims + - name: WS-Federation authentication + uid: security/authentication/ws-federation + - name: Account confirmation and password recovery + uid: security/authentication/accconfirm + - name: Enable QR code generation in Identity + uid: security/authentication/identity-enable-qrcodes + - name: Two-factor authentication with SMS + uid: security/authentication/2fa + - name: Use Cookie Authentication without Identity + uid: security/authentication/cookie + - name: Azure Active Directory + items: + - name: Overview + uid: security/authentication/azure-active-directory/index + - name: Integrate Azure AD into a web app + href: https://azure.microsoft.com/documentation/samples/active-directory-dotnet-webapp-openidconnect-aspnetcore/ + - name: Integrate Azure AD B2C into a web app + uid: security/authentication/azure-ad-b2c + - name: Integrate Azure AD B2C into a web API + uid: security/authentication/azure-ad-b2c-webapi + - name: Call a web API from WPF + href: https://azure.microsoft.com/documentation/samples/active-directory-dotnet-native-aspnetcore/ + - name: Call a web API in a web app using Azure AD + href: https://azure.microsoft.com/documentation/samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/ + - name: Secure ASP.NET Core apps with IdentityServer4 + href: https://identityserver4.readthedocs.io/ + - name: Secure ASP.NET Core apps with Azure App Service authentication (Easy Auth) + href: /azure/app-service/app-service-authentication-overview + - name: Individual user accounts + uid: security/authentication/individual + - name: Authorization + items: + - name: Overview + uid: security/authorization/introduction + - name: Create a web app with authorization + uid: security/authorization/secure-data + - name: Razor Pages authorization conventions + uid: security/authorization/razor-pages-authorization + - name: Simple authorization + uid: security/authorization/simple + - name: Role-based authorization + uid: security/authorization/roles + - name: Claims-based authorization + uid: security/authorization/claims + - name: Policy-based authorization + uid: security/authorization/policies + - name: Authorization policy providers + uid: security/authorization/iauthorizationpolicyprovider + - name: Dependency injection in requirement handlers + uid: security/authorization/dependencyinjection + - name: Resource-based authorization + uid: security/authorization/resourcebased + - name: View-based authorization + uid: security/authorization/views + - name: Limit identity by scheme + uid: security/authorization/limitingidentitybyscheme + - name: Data protection + items: + - name: Overview + uid: security/data-protection/introduction + - name: Data protection APIs + uid: security/data-protection/using-data-protection + - name: Consumer APIs + items: + - name: Overview + uid: security/data-protection/consumer-apis/overview + - name: Purpose strings + uid: security/data-protection/consumer-apis/purpose-strings + - name: Purpose hierarchy and multi-tenancy + uid: security/data-protection/consumer-apis/purpose-strings-multitenancy + - name: Hash passwords + uid: security/data-protection/consumer-apis/password-hashing + - name: Limit the lifetime of protected payloads + uid: security/data-protection/consumer-apis/limited-lifetime-payloads + - name: Unprotect payloads whose keys have been revoked + uid: security/data-protection/consumer-apis/dangerous-unprotect + - name: Configuration + items: + - name: Overview + uid: security/data-protection/configuration/index + - name: Configure data protection + uid: security/data-protection/configuration/overview + - name: Default settings + uid: security/data-protection/configuration/default-settings + - name: Machine-wide policy + uid: security/data-protection/configuration/machine-wide-policy + - name: Non-DI aware scenarios + uid: security/data-protection/configuration/non-di-scenarios + - name: Extensibility APIs + items: + - name: Overview + uid: security/data-protection/extensibility/index + - name: Core cryptography extensibility + uid: security/data-protection/extensibility/core-crypto + - name: Key management extensibility + uid: security/data-protection/extensibility/key-management + - name: Miscellaneous APIs + uid: security/data-protection/extensibility/misc-apis + - name: Implementation + items: + - name: Overview + uid: security/data-protection/implementation/index + - name: Authenticated encryption details + uid: security/data-protection/implementation/authenticated-encryption-details + - name: Subkey derivation and authenticated encryption + uid: security/data-protection/implementation/subkeyderivation + - name: Context headers + uid: security/data-protection/implementation/context-headers + - name: Key management + uid: security/data-protection/implementation/key-management + - name: Key storage providers + uid: security/data-protection/implementation/key-storage-providers + - name: Key encryption at rest + uid: security/data-protection/implementation/key-encryption-at-rest + - name: Key immutability and settings + uid: security/data-protection/implementation/key-immutability + - name: Key storage format + uid: security/data-protection/implementation/key-storage-format + - name: Ephemeral data protection providers + uid: security/data-protection/implementation/key-storage-ephemeral + - name: Compatibility + items: + - name: Overview + uid: security/data-protection/compatibility/index + - name: Replace machineKey in ASP.NET + uid: security/data-protection/compatibility/replacing-machinekey + - name: Protect secrets in development + uid: security/app-secrets + - name: Enforce HTTPS + uid: security/enforcing-ssl + - name: EU General Data Protection Regulation (GDPR) support + uid: security/gdpr + - name: Azure Key Vault configuration provider + uid: security/key-vault-configuration + - name: Anti-request forgery + uid: security/anti-request-forgery + - name: Prevent open redirect attacks + uid: security/preventing-open-redirects + - name: Prevent Cross-Site Scripting + uid: security/cross-site-scripting + - name: Enable Cross-Origin Requests (CORS) + uid: security/cors + - name: Share cookies among apps + uid: security/cookie-sharing + - name: IP safelist + uid: security/ip-safelist +- name: Performance + items: + - name: Overview + uid: performance/performance-best-practices + - name: Response caching + items: + - name: Overview + uid: performance/caching/response + - name: In-memory cache + uid: performance/caching/memory + - name: Distributed caching + uid: performance/caching/distributed + - name: Response caching middleware + uid: performance/caching/middleware + - name: Response compression + uid: performance/response-compression + - name: Diagnostic tools + uid: performance/diagnostic-tools + - name: Load and stress testing + uid: test/loadtests +- name: Globalization and localization + items: + - name: Overview + uid: fundamentals/localization + - name: Portable Object localization + uid: fundamentals/portable-object-localization +- name: Advanced + items: + - name: URL rewriting + uid: fundamentals/url-rewriting + - name: File providers + uid: fundamentals/file-providers + - name: Request-feature interfaces + uid: fundamentals/request-features + - name: Access HttpContext + uid: fundamentals/httpcontext + - name: Change tokens + uid: fundamentals/change-tokens + - name: Open Web Interface for .NET (OWIN) + uid: fundamentals/owin + - name: Background tasks with hosted services + uid: fundamentals/host/hosted-services + - name: Hosting startup assemblies + uid: fundamentals/configuration/platform-specific-configuration + - name: Microsoft.AspNetCore.App metapackage + uid: fundamentals/metapackage-app + - name: Microsoft.AspNetCore.All metapackage + uid: fundamentals/metapackage + - name: Logging with LoggerMessage + uid: fundamentals/logging/loggermessage + - name: Use a file watcher + uid: tutorials/dotnet-watch + items: + - name: Factory-based middleware + uid: fundamentals/middleware/extensibility + - name: Factory-based middleware with third-party container + uid: fundamentals/middleware/extensibility-third-party-container +- name: Migration + items: + - name: 2.2 to 3.0 + uid: migration/22-to-30 + - name: 2.1 to 2.2 + uid: migration/21-to-22 + - name: 2.0 to 2.1 + uid: migration/20_21 + - name: 1.x to 2.0 + items: + - name: Overview + uid: migration/1x-to-2x/index + - name: Authentication and Identity + uid: migration/1x-to-2x/identity-2x + - name: ASP.NET to ASP.NET Core + items: + - name: Overview + uid: migration/proper-to-2x/index + - name: MVC + uid: migration/mvc + - name: Web API + uid: migration/webapi + - name: Configuration + uid: migration/configuration + - name: Authentication and Identity + uid: migration/identity + - name: ClaimsPrincipal.Current + uid: migration/claimsprincipal-current + - name: Membership to Identity + uid: migration/proper-to-2x/membership-to-core-identity + - name: HTTP modules to middleware + uid: migration/http-modules + - name: Logging (not ASP.NET Core) + uid: migration/logging-nonaspnetcore +- name: API reference + href: /dotnet/api/?view=aspnetcore-2.1 +- name: Contribute + href: https://github.com/aspnet/Docs/blob/master/CONTRIBUTING.md diff --git a/aspnetcore/tutorials/first-mongo-app.md b/aspnetcore/tutorials/first-mongo-app.md index 917189150559..0dd4f6fdfc9b 100644 --- a/aspnetcore/tutorials/first-mongo-app.md +++ b/aspnetcore/tutorials/first-mongo-app.md @@ -4,7 +4,7 @@ author: prkhandelwal description: This tutorial demonstrates how to build an ASP.NET Core web API using a MongoDB NoSQL database. ms.author: scaddie ms.custom: "mvc, seodec18" -ms.date: 11/29/2018 +ms.date: 01/23/2019 uid: tutorials/first-mongo-app --- # Create a web API with ASP.NET Core and MongoDB @@ -48,11 +48,11 @@ In this tutorial, you learn how to: ## Configure MongoDB -If using Windows, MongoDB is installed at *C:\Program Files\MongoDB* by default. Add *C:\Program Files\MongoDB\Server\\bin* to the `Path` environment variable. This change enables MongoDB access from anywhere on your development machine. +If using Windows, MongoDB is installed at *C:\\Program Files\\MongoDB* by default. Add *C:\\Program Files\\MongoDB\\Server\\\\\bin* to the `Path` environment variable. This change enables MongoDB access from anywhere on your development machine. Use the mongo Shell in the following steps to create a database, make collections, and store documents. For more information on mongo Shell commands, see [Working with the mongo Shell](https://docs.mongodb.com/manual/mongo/#working-with-the-mongo-shell). -1. Choose a directory on your development machine for storing the data. For example, *C:\BooksData* on Windows. Create the directory if it doesn't exist. The mongo Shell doesn't create new directories. +1. Choose a directory on your development machine for storing the data. For example, *C:\\BooksData* on Windows. Create the directory if it doesn't exist. The mongo Shell doesn't create new directories. 1. Open a command shell. Run the following command to connect to MongoDB on default port 27017. Remember to replace `` with the directory you chose in the previous step. ```console @@ -182,7 +182,13 @@ The database is ready. You can start creating the ASP.NET Core web API. [!code-csharp[](first-mongo-app/sample/BooksApi/Models/Book.cs)] -In the preceding class, the `Id` property is required for mapping the Common Language Runtime (CLR) object to the MongoDB collection. Other properties in the class are decorated with the `[BsonElement]` attribute. The attribute's value represents the property name in the MongoDB collection. +In the preceding class, the `Id` property: + +* Is required for mapping the Common Language Runtime (CLR) object to the MongoDB collection. +* Is annotated with `[BsonId]` to designate this property as the document's primary key. +* Is annotated with `[BsonRepresentation(BsonType.ObjectId)]` to allow passing the parameter as type `string` instead of `ObjectId`. Mongo handles the conversion from `string` to `ObjectId`. + +Other properties in the class are annotated with the `[BsonElement]` attribute. The attribute's value represents the property name in the MongoDB collection. ## Add a CRUD operations class diff --git a/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Models/Book.cs b/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Models/Book.cs index 1775d93fcdea..482237acb824 100644 --- a/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Models/Book.cs +++ b/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Models/Book.cs @@ -5,7 +5,9 @@ namespace BooksApi.Models { public class Book { - public ObjectId Id { get; set; } + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string Id { get; set; } [BsonElement("Name")] public string BookName { get; set; } diff --git a/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Services/BookService.cs b/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Services/BookService.cs index 197fbd3bbe6d..f833e1a23d13 100644 --- a/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Services/BookService.cs +++ b/aspnetcore/tutorials/first-mongo-app/sample/BooksApi/Services/BookService.cs @@ -3,7 +3,6 @@ using System.Linq; using BooksApi.Models; using Microsoft.Extensions.Configuration; -using MongoDB.Bson; using MongoDB.Driver; namespace BooksApi.Services @@ -28,9 +27,7 @@ public List Get() public Book Get(string id) { - var docId = new ObjectId(id); - - return _books.Find(book => book.Id == docId).FirstOrDefault(); + return _books.Find(book => book.Id == id).FirstOrDefault(); } public Book Create(Book book) @@ -41,9 +38,7 @@ public Book Create(Book book) public void Update(string id, Book bookIn) { - var docId = new ObjectId(id); - - _books.ReplaceOne(book => book.Id == docId, bookIn); + _books.ReplaceOne(book => book.Id == id, bookIn); } public void Remove(Book bookIn) @@ -51,7 +46,7 @@ public void Remove(Book bookIn) _books.DeleteOne(book => book.Id == bookIn.Id); } - public void Remove(ObjectId id) + public void Remove(string id) { _books.DeleteOne(book => book.Id == id); } diff --git a/aspnetcore/tutorials/first-mvc-app/adding-view.md b/aspnetcore/tutorials/first-mvc-app/adding-view.md index d0f8da403974..ccdaa82f48ea 100644 --- a/aspnetcore/tutorials/first-mvc-app/adding-view.md +++ b/aspnetcore/tutorials/first-mvc-app/adding-view.md @@ -88,7 +88,7 @@ Select the menu links (**MvcMovie**, **Home**, and **Privacy**). Each page shows The following markup shows the highlighted changes: -[!code-html[](~/tutorials/first-mvc-app/start-mvc/sample/MvcMovie22/Views/Shared/_Layout.cshtml?highlight=6,24)] +[!code-html[](~/tutorials/first-mvc-app/start-mvc/sample/MvcMovie22/Views/Shared/_Layout.cshtml?highlight=6,24,51)] In the preceding markup, the `asp-area` [anchor Tag Helper attribute](xref:mvc/views/tag-helpers/builtin-th/anchor-tag-helper) was omitted because this app is not using [Areas](xref:mvc/controllers/areas). @@ -99,7 +99,7 @@ In the preceding markup, the `asp-area` [anchor Tag Helper attribute](xref:mvc/v **Note**: The `Movies` controller has not been implemented. At this point, the `Movie App` link is not functional. -Save your changes and select the **Privacy** link. Notice how the title on the browser tab displays **Privacy - Movie App** instead of **Privacy - Mvc Movie**: +Save your changes and select the **Privacy** link. Notice how the title on the browser tab displays **Privacy Policy - Movie App** instead of **Privacy Policy - Mvc Movie**: ![Privacy tab](~/tutorials/first-mvc-app/adding-view/_static/about2.png) diff --git a/aspnetcore/tutorials/first-mvc-app/details.md b/aspnetcore/tutorials/first-mvc-app/details.md index 2cd6975b75b9..2010b524c379 100644 --- a/aspnetcore/tutorials/first-mvc-app/details.md +++ b/aspnetcore/tutorials/first-mvc-app/details.md @@ -19,7 +19,7 @@ The MVC scaffolding engine that created this action method adds a comment showin [!code-csharp[](start-mvc/sample/MvcMovie/Startup.cs?highlight=5&name=snippet_1)] -EF makes it easy to search for data using the `SingleOrDefaultAsync` method. An important security feature built into the method is that the code verifies that the search method has found a movie before it tries to do anything with it. For example, a hacker could introduce errors into the site by changing the URL created by the links from `http://localhost:xxxx/Movies/Details/1` to something like `http://localhost:xxxx/Movies/Details/12345` (or some other value that doesn't represent an actual movie). If you didn't check for a null movie, the app would throw an exception. +EF makes it easy to search for data using the `FirstOrDefaultAsync` method. An important security feature built into the method is that the code verifies that the search method has found a movie before it tries to do anything with it. For example, a hacker could introduce errors into the site by changing the URL created by the links from `http://localhost:xxxx/Movies/Details/1` to something like `http://localhost:xxxx/Movies/Details/12345` (or some other value that doesn't represent an actual movie). If you didn't check for a null movie, the app would throw an exception. Examine the `Delete` and `DeleteConfirmed` methods. diff --git a/aspnetcore/tutorials/first-mvc-app/index.md b/aspnetcore/tutorials/first-mvc-app/index.md index e39376b9d3fe..60815575f635 100644 --- a/aspnetcore/tutorials/first-mvc-app/index.md +++ b/aspnetcore/tutorials/first-mvc-app/index.md @@ -1,12 +1,12 @@ --- -title: Create a web app with ASP.NET Core MVC on Windows with Visual Studio +title: Create a web app with ASP.NET Core MVC author: rick-anderson -description: See the table of contents for an introduction to ASP.NET Core MVC using Visual Studio on Windows. +description: See the table of contents for an introduction to ASP.NET Core MVC. ms.author: riande ms.date: 10/26/2017 uid: tutorials/first-mvc-app/index --- -# Create a web app with ASP.NET Core MVC on Windows with Visual Studio +# Create a web app with ASP.NET Core MVC [!INCLUDE [consider RP](~/includes/razor.md)] diff --git a/aspnetcore/tutorials/first-web-api.md b/aspnetcore/tutorials/first-web-api.md index ab5ac386026b..b2111d78b324 100644 --- a/aspnetcore/tutorials/first-web-api.md +++ b/aspnetcore/tutorials/first-web-api.md @@ -4,7 +4,7 @@ author: rick-anderson description: Build a web API with ASP.NET Core MVC ms.author: riande ms.custom: mvc -ms.date: 12/10/2018 +ms.date: 01/24/2019 uid: tutorials/first-web-api --- @@ -163,14 +163,10 @@ The *database context* is the main class that coordinates Entity Framework funct * Right-click the *Models* folder and select **Add** > **Class**. Name the class *TodoContext* and click **Add**. -# [Visual Studio Code](#tab/visual-studio-code) +# [Visual Studio Code / Visual Studio for Mac](#tab/visual-studio-code+visual-studio-mac) * Add a `TodoContext` class to the *Models* folder. -# [Visual Studio for Mac](#tab/visual-studio-mac) - -* Add a `TodoContext` class in the *Models* folder: - --- * Replace the template code with the following code: @@ -202,14 +198,10 @@ The preceding code: ![Add new Item dialog with controller in search box and web api controller selected](first-web-api/_static/new_controller.png) -# [Visual Studio Code](#tab/visual-studio-code) +# [Visual Studio Code / Visual Studio for Mac](#tab/visual-studio-code+visual-studio-mac) * In the *Controllers* folder, create a class named `TodoController`. -# [Visual Studio for Mac](#tab/visual-studio-mac) - -* In the *Controllers* folder, add the class `TodoController`. - --- * Replace the template code with the following code: @@ -260,14 +252,12 @@ The [`[HttpGet]`](/dotnet/api/microsoft.aspnetcore.mvc.httpgetattribute) attribu [!code-csharp[](first-web-api/samples/2.2/TodoApi/Controllers/TodoController.cs?name=TodoController&highlight=3)] * Replace `[controller]` with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. For this sample, the controller class name is **Todo**Controller, so the controller name is "todo". ASP.NET Core [routing](xref:mvc/controllers/routing) is case insensitive. -* If the `[HttpGet]` attribute has a route template (for example, `[HttpGet("/products")]`, append that to the path. This sample doesn't use a template. For more information, see [Attribute routing with Http[Verb] attributes](xref:mvc/controllers/routing#attribute-routing-with-httpverb-attributes). +* If the `[HttpGet]` attribute has a route template (for example, `[HttpGet("products")]`), append that to the path. This sample doesn't use a template. For more information, see [Attribute routing with Http[Verb] attributes](xref:mvc/controllers/routing#attribute-routing-with-httpverb-attributes). In the following `GetTodoItem` method, `"{id}"` is a placeholder variable for the unique identifier of the to-do item. When `GetTodoItem` is invoked, the value of `"{id}"` in the URL is provided to the method in its`id` parameter. [!code-csharp[](first-web-api/samples/2.2/TodoApi/Controllers/TodoController.cs?name=snippet_GetByID&highlight=1-2)] -The `Name = "GetTodo"` parameter creates a named route. You'll see later how the app can use the name to create an HTTP link using the route name. - ## Return values The return type of the `GetTodoItems` and `GetTodoItem` methods is [ActionResult\ type](xref:web-api/action-return-types#actionresultt-type). ASP.NET Core automatically serializes the object to [JSON](https://www.json.org/) and writes the JSON into the body of the response message. The response code for this return type is 200, assuming there are no unhandled exceptions. Unhandled exceptions are translated into 5xx errors. @@ -308,9 +298,9 @@ The preceding code is an HTTP POST method, as indicated by the [[HttpPost]](/dot The `CreatedAtAction` method: -* Returns a 201 response. HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server. -* Adds a Location header to the response. The Location header specifies the URI of the newly created to-do item. For more information, see [10.2.2 201 Created](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html). -* Uses the "GetTodo" named route to create the URL. The "GetTodo" named route is defined in `GetTodoItem`: +* Returns an HTTP 201 status code, if successful. HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server. +* Adds a `Location` header to the response. The `Location` header specifies the URI of the newly created to-do item. For more information, see [10.2.2 201 Created](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html). +* References the `GetTodoItem` action to create the `Location` header's URI. The C# `nameof` keyword is used to avoid hard-coding the action name in the `CreatedAtAction` call. [!code-csharp[](first-web-api/samples/2.2/TodoApi/Controllers/TodoController.cs?name=snippet_GetByID&highlight=1-2)] @@ -334,7 +324,7 @@ The `CreatedAtAction` method: ![Postman with create request](first-web-api/_static/create.png) - If you get a 405 Method Not Allowed error, it's probably the result of not compiling the project after adding the after adding the `PostTodoItem` method. + If you get a 405 Method Not Allowed error, it's probably the result of not compiling the project after adding the `PostTodoItem` method. ### Test the location header URI diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Controllers/TodoController.cs b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Controllers/TodoController.cs deleted file mode 100644 index cd6afbcd08ed..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Controllers/TodoController.cs +++ /dev/null @@ -1,103 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Linq; -using TodoApi.Models; - -#region TodoController -namespace TodoApi.Controllers -{ - [Route("api/[controller]")] - public class TodoController : ControllerBase - { - private readonly TodoContext _context; - #endregion - - public TodoController(TodoContext context) - { - _context = context; - - if (_context.TodoItems.Count() == 0) - { - _context.TodoItems.Add(new TodoItem { Name = "Item1" }); - _context.SaveChanges(); - } - } - - #region snippet_GetAll - [HttpGet] - public List GetAll() - { - return _context.TodoItems.ToList(); - } - - #region snippet_GetByID - [HttpGet("{id}", Name = "GetTodo")] - public IActionResult GetById(long id) - { - var item = _context.TodoItems.Find(id); - if (item == null) - { - return NotFound(); - } - return Ok(item); - } - #endregion - #endregion - - #region snippet_Create - [HttpPost] - public IActionResult Create([FromBody] TodoItem item) - { - if (item == null) - { - return BadRequest(); - } - - _context.TodoItems.Add(item); - _context.SaveChanges(); - - return CreatedAtRoute("GetTodo", new { id = item.Id }, item); - } - #endregion - - #region snippet_Update - [HttpPut("{id}")] - public IActionResult Update(long id, [FromBody] TodoItem item) - { - if (item == null || item.Id != id) - { - return BadRequest(); - } - - var todo = _context.TodoItems.Find(id); - if (todo == null) - { - return NotFound(); - } - - todo.IsComplete = item.IsComplete; - todo.Name = item.Name; - - _context.TodoItems.Update(todo); - _context.SaveChanges(); - return NoContent(); - } - #endregion - - #region snippet_Delete - [HttpDelete("{id}")] - public IActionResult Delete(long id) - { - var todo = _context.TodoItems.Find(id); - if (todo == null) - { - return NotFound(); - } - - _context.TodoItems.Remove(todo); - _context.SaveChanges(); - return NoContent(); - } - #endregion - } -} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Controllers/TodoController2.cs b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Controllers/TodoController2.cs deleted file mode 100644 index 882a5f6e0ecd..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Controllers/TodoController2.cs +++ /dev/null @@ -1,29 +0,0 @@ -#if NEVER -// This controller is used only for documentation purposes. -#region snippet_todo1 -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Linq; -using TodoApi.Models; - -namespace TodoApi.Controllers -{ - [Route("api/[controller]")] - public class TodoController : ControllerBase - { - private readonly TodoContext _context; - - public TodoController(TodoContext context) - { - _context = context; - - if (_context.TodoItems.Count() == 0) - { - _context.TodoItems.Add(new TodoItem { Name = "Item1" }); - _context.SaveChanges(); - } - } - } -} -#endregion -#endif diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Models/TodoContext.cs b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Models/TodoContext.cs deleted file mode 100644 index e3f066b538c4..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Models/TodoContext.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace TodoApi.Models -{ - public class TodoContext : DbContext - { - public TodoContext(DbContextOptions options) - : base(options) - { - } - - public DbSet TodoItems { get; set; } - } -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Models/TodoItem.cs b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Models/TodoItem.cs deleted file mode 100644 index d3eef6e3af56..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Models/TodoItem.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace TodoApi.Models -{ - public class TodoItem - { - public long Id { get; set; } - public string Name { get; set; } - public bool IsComplete { get; set; } - } -} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Program.cs b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Program.cs deleted file mode 100644 index 737da22f224e..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Program.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using System.IO; - -namespace TodoApi -{ - public class Program - { - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseStartup() - .Build(); - - host.Run(); - } - } -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Startup.cs b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Startup.cs deleted file mode 100644 index 2529fcbb1ba2..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Startup.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using TodoApi.Models; - -namespace TodoApi -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - services.AddDbContext(opt => - opt.UseInMemoryDatabase("TodoList")); - services.AddMvc(); - } - - public void Configure(IApplicationBuilder app) - { - app.UseMvc(); - } - } -} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Startup2.cs b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Startup2.cs deleted file mode 100644 index b974afaf6b2b..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/Startup2.cs +++ /dev/null @@ -1,29 +0,0 @@ -#if NEVER -// This class is used only for documentation purposes. -using Microsoft.AspNetCore.Builder; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using TodoApi.Models; - -namespace TodoApi -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - services.AddDbContext(opt => - opt.UseInMemoryDatabase("TodoList")); - services.AddMvc(); - } - -#region snippet_Configure - public void Configure(IApplicationBuilder app) - { - app.UseDefaultFiles(); - app.UseStaticFiles(); - app.UseMvc(); - } -#endregion - } -} -#endif \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/TodoApi.csproj b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/TodoApi.csproj deleted file mode 100644 index 89941b8e745a..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/TodoApi.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - netcoreapp2.0 - ASP.NET Core 2.0 - - - - - - - - - - - - - diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/appsettings.Development.json b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/appsettings.Development.json deleted file mode 100644 index fa8ce71a97a3..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/appsettings.Development.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/appsettings.json b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/appsettings.json deleted file mode 100644 index 5fff67bacc46..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Warning" - } - } -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/wwwroot/index.html b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/wwwroot/index.html deleted file mode 100644 index 6d7062bb3c84..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/wwwroot/index.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - To-do CRUD - - - -

To-do CRUD

-

Add

-
- - -
- -
-

Edit

-
- - - - - -
-
- -

- - - - - - - - - -
Is CompleteName
- - - - - diff --git a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/wwwroot/site.js b/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/wwwroot/site.js deleted file mode 100644 index 45f2b766f21f..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.0/TodoApi/wwwroot/site.js +++ /dev/null @@ -1,119 +0,0 @@ -// -const uri = 'api/todo'; -let todos = null; -function getCount(data) { - const el = $('#counter'); - let name = 'to-do'; - if (data) { - if (data > 1) { - name = 'to-dos'; - } - el.text(data + ' ' + name); - } else { - el.html('No ' + name); - } -} - -// -$(document).ready(function () { - getData(); -}); - -function getData() { - $.ajax({ - type: 'GET', - url: uri, - success: function (data) { - $('#todos').empty(); - getCount(data.length); - $.each(data, function (key, item) { - const checked = item.isComplete ? 'checked' : ''; - - $('' + - '' + item.name + '' + - '' + - '' + - '').appendTo($('#todos')); - }); - - todos = data; - } - }); -} -// - -// -function addItem() { - const item = { - 'name': $('#add-name').val(), - 'isComplete': false - }; - - $.ajax({ - type: 'POST', - accepts: 'application/json', - url: uri, - contentType: 'application/json', - data: JSON.stringify(item), - error: function (jqXHR, textStatus, errorThrown) { - alert('here'); - }, - success: function (result) { - getData(); - $('#add-name').val(''); - } - }); -} -// - -function deleteItem(id) { - // - $.ajax({ - url: uri + '/' + id, - type: 'DELETE', - success: function (result) { - getData(); - } - }); - // -} - -function editItem(id) { - $.each(todos, function (key, item) { - if (item.id === id) { - $('#edit-name').val(item.name); - $('#edit-id').val(item.id); - $('#edit-isComplete')[0].checked = item.isComplete; - } - }); - $('#spoiler').css({ 'display': 'block' }); -} - -$('.my-form').on('submit', function () { - const item = { - 'name': $('#edit-name').val(), - 'isComplete': $('#edit-isComplete').is(':checked'), - 'id': $('#edit-id').val() - }; - - // - $.ajax({ - url: uri + '/' + $('#edit-id').val(), - type: 'PUT', - accepts: 'application/json', - contentType: 'application/json', - data: JSON.stringify(item), - success: function (result) { - getData(); - } - }); - // - - closeInput(); - return false; -}); - -function closeInput() { - $('#spoiler').css({ 'display': 'none' }); -} -// \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Controllers/TodoController.cs b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Controllers/TodoController.cs deleted file mode 100644 index 64f09603098c..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Controllers/TodoController.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Linq; -using TodoApi.Models; - -#region TodoController -namespace TodoApi.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class TodoController : ControllerBase - { - private readonly TodoContext _context; - #endregion - - public TodoController(TodoContext context) - { - _context = context; - - if (_context.TodoItems.Count() == 0) - { - _context.TodoItems.Add(new TodoItem { Name = "Item1" }); - _context.SaveChanges(); - } - } - - #region snippet_GetAll - [HttpGet] - public ActionResult> GetAll() - { - return _context.TodoItems.ToList(); - } - - #region snippet_GetByID - [HttpGet("{id}", Name = "GetTodo")] - public ActionResult GetById(long id) - { - var item = _context.TodoItems.Find(id); - if (item == null) - { - return NotFound(); - } - return item; - } - #endregion - #endregion - - #region snippet_Create - [HttpPost] - public ActionResult Create(TodoItem item) - { - _context.TodoItems.Add(item); - _context.SaveChanges(); - - return CreatedAtRoute("GetTodo", new { id = item.Id }, item); - } - #endregion - - #region snippet_Update - [HttpPut("{id}")] - public ActionResult Update(long id, TodoItem item) - { - var todo = _context.TodoItems.Find(id); - if (todo == null) - { - return NotFound(); - } - - todo.IsComplete = item.IsComplete; - todo.Name = item.Name; - - _context.TodoItems.Update(todo); - _context.SaveChanges(); - return NoContent(); - } - #endregion - - #region snippet_Delete - [HttpDelete("{id}")] - public ActionResult Delete(long id) - { - var todo = _context.TodoItems.Find(id); - if (todo == null) - { - return NotFound(); - } - - _context.TodoItems.Remove(todo); - _context.SaveChanges(); - return NoContent(); - } - #endregion - } -} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Controllers/TodoController2.cs b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Controllers/TodoController2.cs deleted file mode 100644 index 1e19ed09b5c5..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Controllers/TodoController2.cs +++ /dev/null @@ -1,32 +0,0 @@ -#if NEVER -// This controller is used only for documentation purposes. -#region snippet_todo1 -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Linq; -using TodoApi.Models; - -namespace TodoApi.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class TodoController : ControllerBase - { - private readonly TodoContext _context; - - public TodoController(TodoContext context) - { - _context = context; - - if (_context.TodoItems.Count() == 0) - { - // Create a new TodoItem if collection is empty, - // which means you can't delete all TodoItems. - _context.TodoItems.Add(new TodoItem { Name = "Item1" }); - _context.SaveChanges(); - } - } - } -} -#endregion -#endif diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Models/TodoContext.cs b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Models/TodoContext.cs deleted file mode 100644 index 6e59e3637896..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Models/TodoContext.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace TodoApi.Models -{ - public class TodoContext : DbContext - { - public TodoContext(DbContextOptions options) - : base(options) - { - } - - public DbSet TodoItems { get; set; } - } -} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Models/TodoItem.cs b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Models/TodoItem.cs deleted file mode 100644 index d3eef6e3af56..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Models/TodoItem.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace TodoApi.Models -{ - public class TodoItem - { - public long Id { get; set; } - public string Name { get; set; } - public bool IsComplete { get; set; } - } -} \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Startup.cs b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Startup.cs deleted file mode 100644 index 502b04a4346f..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Startup.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Unused usings removed -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using TodoApi.Models; // TodoContext -using Microsoft.EntityFrameworkCore; // UseInMemoryDatabase - -namespace TodoApi -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. - //Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddDbContext(opt => - opt.UseInMemoryDatabase("TodoList")); - services.AddMvc() - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); - } - - // This method gets called by the runtime. - //Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseHsts(); - } - - app.UseHttpsRedirection(); - app.UseMvc(); - } - } -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Startup2.cs b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Startup2.cs deleted file mode 100644 index 0ed31a6e15ee..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/Startup2.cs +++ /dev/null @@ -1,49 +0,0 @@ -#if NEVER -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using TodoApi.Models; - -namespace TodoApi -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - public void ConfigureServices(IServiceCollection services) - { - services.AddDbContext(opt => - opt.UseInMemoryDatabase("TodoList")); - services.AddMvc() - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); - } - -#region snippet_Configure - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseHsts(); - } - - app.UseHttpsRedirection(); - app.UseDefaultFiles(); - app.UseStaticFiles(); - app.UseMvc(); - } -#endregion - } -} -#endif \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/TodoApi.csproj b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/TodoApi.csproj deleted file mode 100644 index 523a787b6bad..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/TodoApi.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - netcoreapp2.1 - >= ASP.NET Core 2.1 - - - - - - - - - \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/appsettings.Development.json b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/appsettings.Development.json deleted file mode 100644 index e203e9407e74..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/appsettings.json b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/appsettings.json deleted file mode 100644 index def9159a7d94..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/wwwroot/index.html b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/wwwroot/index.html deleted file mode 100644 index c1d795786140..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/wwwroot/index.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - To-do CRUD - - - -

To-do CRUD

-

Add

-
- - -
- -
-

Edit

-
- - - - - -
-
- -

- - - - - - - - - -
Is CompleteName
- - - - - \ No newline at end of file diff --git a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/wwwroot/site.js b/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/wwwroot/site.js deleted file mode 100644 index 276f52fdd7ab..000000000000 --- a/aspnetcore/tutorials/first-web-api/samples/2.1/TodoApi/wwwroot/site.js +++ /dev/null @@ -1,109 +0,0 @@ -const uri = 'api/todo'; -let todos = null; -function getCount(data) { - const el = $('#counter'); - let name = 'to-do'; - if (data) { - if (data > 1) { - name = 'to-dos'; - } - el.text(data + ' ' + name); - } else { - el.html('No ' + name); - } -} - -$(document).ready(function () { - getData(); -}); - -function getData() { - $.ajax({ - type: 'GET', - url: uri, - cache: false, - success: function (data) { - $('#todos').empty(); - getCount(data.length); - $.each(data, function (key, item) { - const checked = item.isComplete ? 'checked' : ''; - - $('' + - '' + item.name + '' + - '' + - '' + - '').appendTo($('#todos')); - }); - - todos = data; - } - }); -} - -function addItem() { - const item = { - 'name': $('#add-name').val(), - 'isComplete': false - }; - - $.ajax({ - type: 'POST', - accepts: 'application/json', - url: uri, - contentType: 'application/json', - data: JSON.stringify(item), - error: function (jqXHR, textStatus, errorThrown) { - alert('here'); - }, - success: function (result) { - getData(); - $('#add-name').val(''); - } - }); -} - -function deleteItem(id) { - $.ajax({ - url: uri + '/' + id, - type: 'DELETE', - success: function (result) { - getData(); - } - }); -} - -function editItem(id) { - $.each(todos, function (key, item) { - if (item.id === id) { - $('#edit-name').val(item.name); - $('#edit-id').val(item.id); - $('#edit-isComplete')[0].checked = item.isComplete; - } - }); - $('#spoiler').css({ 'display': 'block' }); -} - -$('.my-form').on('submit', function () { - const item = { - 'name': $('#edit-name').val(), - 'isComplete': $('#edit-isComplete').is(':checked'), - 'id': $('#edit-id').val() - }; - - $.ajax({ - url: uri + '/' + $('#edit-id').val(), - type: 'PUT', - accepts: 'application/json', - contentType: 'application/json', - data: JSON.stringify(item), - success: function (result) { - getData(); - } - }); - closeInput(); - return false; -}); - -function closeInput() { - $('#spoiler').css({ 'display': 'none' }); -} diff --git a/aspnetcore/tutorials/first-web-api/samples/2.2/TodoApi/Controllers/TodoController.cs b/aspnetcore/tutorials/first-web-api/samples/2.2/TodoApi/Controllers/TodoController.cs index 7b1ed086babe..31366d02cf57 100644 --- a/aspnetcore/tutorials/first-web-api/samples/2.2/TodoApi/Controllers/TodoController.cs +++ b/aspnetcore/tutorials/first-web-api/samples/2.2/TodoApi/Controllers/TodoController.cs @@ -58,26 +58,26 @@ public async Task> GetTodoItem(long id) #region snippet_Create // POST: api/Todo [HttpPost] - public async Task> PostTodoItem(TodoItem todoItem) + public async Task> PostTodoItem(TodoItem item) { - _context.TodoItems.Add(todoItem); + _context.TodoItems.Add(item); await _context.SaveChangesAsync(); - return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem); + return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item); } #endregion #region snippet_Update // PUT: api/Todo/5 [HttpPut("{id}")] - public async Task PutTodoItem(long id, TodoItem todoItem) + public async Task PutTodoItem(long id, TodoItem item) { - if (id != todoItem.Id) + if (id != item.Id) { return BadRequest(); } - _context.Entry(todoItem).State = EntityState.Modified; + _context.Entry(item).State = EntityState.Modified; await _context.SaveChangesAsync(); return NoContent(); @@ -87,9 +87,10 @@ public async Task PutTodoItem(long id, TodoItem todoItem) #region snippet_Delete // DELETE: api/Todo/5 [HttpDelete("{id}")] - public async Task> DeleteTodoItem(long id) + public async Task DeleteTodoItem(long id) { var todoItem = await _context.TodoItems.FindAsync(id); + if (todoItem == null) { return NotFound(); @@ -98,7 +99,7 @@ public async Task> DeleteTodoItem(long id) _context.TodoItems.Remove(todoItem); await _context.SaveChangesAsync(); - return todoItem; + return NoContent(); } #endregion } diff --git a/aspnetcore/tutorials/razor-pages/model.md b/aspnetcore/tutorials/razor-pages/model.md index a39de5ff2505..488e91bcf27b 100644 --- a/aspnetcore/tutorials/razor-pages/model.md +++ b/aspnetcore/tutorials/razor-pages/model.md @@ -17,7 +17,7 @@ In this section, classes are added for managing movies in a database. These clas The model classes are known as POCO classes (from "plain-old CLR objects") because they don't have any dependency on EF Core. They define the properties of the data that are stored in the database. -[View or download](https://github.com/aspnet/Docs/tree/master/aspnetcore/tutorials/razor-pages-start/sample/) sample. +[View or download](https://github.com/aspnet/Docs/tree/master/aspnetcore/tutorials/razor-pages/razor-pages-start) sample. ## Add a data model @@ -222,7 +222,7 @@ The `RazorPagesMovieContext` coordinates EF Core functionality (Create, Read, Up [!code-csharp[](~/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie22/Data/RazorPagesMovieContext.cs)] -The preceding code creates a [DbSet/\](/dotnet/api/microsoft.entityframeworkcore.dbset-1) property for the entity set. In Entity Framework terminology, an entity set typically corresponds to a database table. An entity corresponds to a row in the table. +The preceding code creates a [`DbSet`](/dotnet/api/microsoft.entityframeworkcore.dbset-1) property for the entity set. In Entity Framework terminology, an entity set typically corresponds to a database table. An entity corresponds to a row in the table. The name of the connection string is passed in to the context by calling a method on a [DbContextOptions](/dotnet/api/microsoft.entityframeworkcore.dbcontextoptions) object. For local development, the [ASP.NET Core configuration system](xref:fundamentals/configuration/index) reads the connection string from the *appsettings.json* file. diff --git a/aspnetcore/tutorials/razor-pages/page.md b/aspnetcore/tutorials/razor-pages/page.md index 9d388f05fe6d..154d0402d042 100644 --- a/aspnetcore/tutorials/razor-pages/page.md +++ b/aspnetcore/tutorials/razor-pages/page.md @@ -103,7 +103,7 @@ The preceding anchor element is a [Tag Helper](xref:mvc/views/tag-helpers/intro) Save your changes, and test the app by clicking on the **RpMovie** link. See the [_Layout.cshtml](https://github.com/aspnet/Docs/blob/master/aspnetcore/tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie22/Pages/Shared/_Layout.cshtml) file in GitHub if you have any problems. -Test the other links (**Home**, **RpMovie**, **Create**, **Edit**, and **Delete**). Each page sets the title, which you can see in the browser tab. When you bookmark a page, the title is used for the bookmark. *Pages/Index.cshtml* and *Pages/Movies/Index.cshtml* currently have the same title, but you can modify them to have different values. +Test the other links (**Home**, **RpMovie**, **Create**, **Edit**, and **Delete**). Each page sets the title, which you can see in the browser tab. When you bookmark a page, the title is used for the bookmark. > [!NOTE] > You may not be able to enter decimal commas in the `Price` field. To support [jQuery validation](https://jqueryvalidation.org/) for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. This [GitHub issue 4076](https://github.com/aspnet/Docs/issues/4076#issuecomment-326590420) for instructions on adding decimal comma. diff --git a/aspnetcore/tutorials/signalr-typescript-webpack.md b/aspnetcore/tutorials/signalr-typescript-webpack.md index 8bb6829dba5b..4bff2278639e 100644 --- a/aspnetcore/tutorials/signalr-typescript-webpack.md +++ b/aspnetcore/tutorials/signalr-typescript-webpack.md @@ -2,7 +2,7 @@ title: Use ASP.NET Core SignalR with TypeScript and Webpack author: ssougnez description: In this tutorial, you configure Webpack to bundle and build an ASP.NET Core SignalR web app whose client is written in TypeScript. -ms.author: scaddie +ms.author: bradyg ms.custom: mvc ms.date: 11/30/2018 uid: tutorials/signalr-typescript-webpack diff --git a/aspnetcore/tutorials/signalr.md b/aspnetcore/tutorials/signalr.md index 63582f4a2bbc..25bff156192d 100644 --- a/aspnetcore/tutorials/signalr.md +++ b/aspnetcore/tutorials/signalr.md @@ -1,8 +1,8 @@ --- title: Get started with ASP.NET Core SignalR -author: tdykstra +author: bradygaster description: In this tutorial, you create a chat app that uses ASP.NET Core SignalR. -ms.author: tdykstra +ms.author: bradyg ms.custom: mvc ms.date: 11/30/2018 uid: tutorials/signalr diff --git a/aspnetcore/tutorials/signalr/sample/wwwroot/js/chat.js b/aspnetcore/tutorials/signalr/sample/wwwroot/js/chat.js index beaa5e28ba8b..f00d6d9ffa0e 100644 --- a/aspnetcore/tutorials/signalr/sample/wwwroot/js/chat.js +++ b/aspnetcore/tutorials/signalr/sample/wwwroot/js/chat.js @@ -2,6 +2,9 @@ var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build(); +//Disable send button until connection is established +document.getElementById("sendButton").disabled = true; + connection.on("ReceiveMessage", function (user, message) { var msg = message.replace(/&/g, "&").replace(//g, ">"); var encodedMsg = user + " says " + msg; @@ -10,7 +13,9 @@ connection.on("ReceiveMessage", function (user, message) { document.getElementById("messagesList").appendChild(li); }); -connection.start().catch(function (err) { +connection.start().then(function(){ + document.getElementById("sendButton").disabled = false; +}).catch(function (err) { return console.error(err.toString()); }); @@ -21,4 +26,4 @@ document.getElementById("sendButton").addEventListener("click", function (event) return console.error(err.toString()); }); event.preventDefault(); -}); \ No newline at end of file +}); diff --git a/aspnetcore/web-api/advanced/conventions.md b/aspnetcore/web-api/advanced/conventions.md index 4f1e235a97a7..69faebcbd819 100644 --- a/aspnetcore/web-api/advanced/conventions.md +++ b/aspnetcore/web-api/advanced/conventions.md @@ -52,7 +52,7 @@ For more information on `[ProducesDefaultResponseType]`, see [Default Response]( [!code-csharp[](conventions/sample/Controllers/ContactsConventionController.cs?name=snippet_ApiConventionTypeAttribute&highlight=2)] -1. `Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute` applied to an assembly — Applies the specified convention type to all controllers in the current assembly. As a recommendation, apply assembly-level attributes to the `Startup` class. +1. `Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute` applied to an assembly — Applies the specified convention type to all controllers in the current assembly. As a recommendation, apply assembly-level attributes in the *Startup.cs* file. In the following example, the default set of conventions is applied to all controllers in the assembly: