Merge pull request #5340 from aspnet/master

Update live with current master
pull/5349/head
Rick Anderson 2018-02-02 13:24:26 -10:00 committed by GitHub
commit cb8f3dbb16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 122 additions and 105 deletions

View File

@ -1,8 +1,8 @@
<sharedListeners>
<!-- Listener for transport events -->
<add name="SignalR-Transports" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRScaleoutLog" />
<add name="SignalR-Transports" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRTransportLog" />
<!-- Listener for scaleout provider events -->
<add name="SignalR-Bus" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRTransportLog" />
<add name="SignalR-Bus" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRScaleoutLog" />
<!-- Listener for hub discovery events -->
<add name="SignalR-Init" type="System.Diagnostics.EventLogTraceListener" initializeData="SignalRInitLog" />
</sharedListeners>

View File

@ -12,9 +12,7 @@ uid: data/ef-mvc/index
---
# Getting started with ASP.NET Core MVC and Entity Framework Core using Visual Studio
Note: A Razor Pages version of this tutorial is available [here](xref:data/ef-rp/intro). The Razor Pages version is easier to follow and covers more EF features.
This series of tutorials teaches you how to create ASP.NET Core MVC web applications that use Entity Framework Core for data access. The tutorials require Visual Studio 2017.
[!INCLUDE[RP better than MVC](../../includes/RP-EF/rp-over-mvc.md)]
1. [Getting started](intro.md)
2. [Create, Read, Update, and Delete operations](crud.md)

View File

@ -14,7 +14,7 @@ uid: data/ef-mvc/intro
By [Tom Dykstra](https://github.com/tdykstra) and [Rick Anderson](https://twitter.com/RickAndMSFT)
A Razor Pages version of this tutorial is available [here](xref:data/ef-rp/intro). The Razor Pages version is easier to follow and covers more EF features. We recommend you follow the [Razor Pages version of this tutorial](xref:data/ef-rp/intro).
[!INCLUDE[RP better than MVC](../../includes/RP-EF/rp-over-mvc.md)]
The Contoso University sample web application demonstrates how to create ASP.NET Core 2.0 MVC web applications using Entity Framework (EF) Core 2.0 and Visual Studio 2017.

View File

@ -193,7 +193,7 @@ Update *pages\departments\edit.cshtml.cs* with the following code:
To detect a concurrency issue, the [OriginalValue](https://docs.microsoft.com/dotnet/api/microsoft.entityframeworkcore.changetracking.propertyentry.originalvalue?view=efcore-2.0#Microsoft_EntityFrameworkCore_ChangeTracking_PropertyEntry_OriginalValue) is updated with the `rowVersion` value from the entity it was fetched. EF Core generates a SQL UPDATE command with a WHERE clause containing the original `RowVersion` value. If no rows are affected by the UPDATE command (no rows have the original `RowVersion` value), a `DbUpdateConcurrencyException` exception is thrown.
[!code-csharp[](intro/samples/cu/Pages/Departments/Edit.cshtml.cs?name=snippet_rv&highlight=24-)]
[!code-csharp[](intro/samples/cu/Pages/Departments/Edit.cshtml.cs?name=snippet_rv&highlight=24-999)]
In the preceding code, `Department.RowVersion` is the value when the entity was fetched. `OriginalValue` is the value in the DB when `FirstOrDefaultAsync` was called in this method.

View File

@ -175,7 +175,7 @@ Run the app and navigate to the instructors page.
Replace *Pages/Instructors/Index.cshtml.cs* with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Index1.cshtml.cs?name=snippet_all&highlight=2,20-)]
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Index1.cshtml.cs?name=snippet_all&highlight=2,20-99)]
The `OnGetAsync` method accepts optional route data for the ID of the selected instructor.
@ -244,7 +244,7 @@ Click on the **Select** link. The row style changes.
Update the `OnGetAsync` method in *Pages/Instructors/Index.cshtml.cs* with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Index2.cshtml.cs?name=snippet_OnGetAsync&highlight=1,8,16-)]
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Index2.cshtml.cs?name=snippet_OnGetAsync&highlight=1,8,16-999)]
Examine the updated query:
@ -271,7 +271,7 @@ The following code populates the view model's `Enrollments` property when a cour
Add the following markup to the end of the *Pages/Courses/Index.cshtml* Razor Page:
[!code-html[](intro/samples/cu/Pages/Instructors/IndexRRD.cshtml?range=60-102&highlight=7-)]
[!code-html[](intro/samples/cu/Pages/Instructors/IndexRRD.cshtml?range=60-102&highlight=7-999)]
The preceding markup displays a list of courses related to an instructor when an instructor is selected.

View File

@ -65,7 +65,7 @@ These two statements enable the view to set the column heading hyperlinks as fol
The method uses LINQ to Entities to specify the column to sort by. The code initializes an `IQueryable<Student> ` before the switch statement, and modifies it in the switch statement:
[!code-csharp[Main](intro/samples/cu/Pages/Students/Index.cshtml.cs?name=snippet_SortOnly&highlight=6-)]
[!code-csharp[Main](intro/samples/cu/Pages/Students/Index.cshtml.cs?name=snippet_SortOnly&highlight=6-999)]
When an`IQueryable` is created or modified, no query is sent to the database. The query isn't executed until the `IQueryable` object is converted into a collection. `IQueryable` are converted to a collection by calling a method such as `ToListAsync`. Therefore, the `IQueryable` code results in a single query that's not executed until the following statement:
@ -174,7 +174,7 @@ In *Students/Index.cshtml.cs*, update the type of `Student` from `IList<Student>
Update the *Students/Index.cshtml.cs* `OnGetAsync` with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Students/Index.cshtml.cs?name=snippet_SortFilterPage&highlight=1-4,7-14,41-)]
[!code-csharp[Main](intro/samples/cu/Pages/Students/Index.cshtml.cs?name=snippet_SortFilterPage&highlight=1-4,7-14,41-999)]
The preceding code adds the page index, the current `sortOrder`, and the `currentFilter` to the method signature.
@ -211,7 +211,7 @@ The two question marks in `PaginatedList.CreateAsync` represent the [null-coales
Update the markup in *Students/Index.cshtml*. The changes are highlighted:
[!code-html[](intro/samples/cu/Pages/Students/Index.cshtml?highlight=28-31,37-40,68-)]
[!code-html[](intro/samples/cu/Pages/Students/Index.cshtml?highlight=28-31,37-40,68-999)]
The column header links use the query string to pass the current search string to the `OnGetAsync` method so that the user can sort within filter results:

View File

@ -44,7 +44,7 @@ When a new course entity is created, it must have a relationship to an existing
Update the Create page model with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Courses/Create.cshtml.cs?highlight=7,18,32-)]
[!code-csharp[Main](intro/samples/cu/Pages/Courses/Create.cshtml.cs?highlight=7,18,32-999)]
The preceding code:
@ -77,7 +77,7 @@ Test the Create page. The Create page displays the department name rather than t
Update the edit page model with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Courses/Edit.cshtml.cs?highlight=8,28,35,36,40,47-)]
[!code-csharp[Main](intro/samples/cu/Pages/Courses/Edit.cshtml.cs?highlight=8,28,35,36,40,47-999)]
The changes are similar to those made in the Create page model. In the preceding code, `PopulateDepartmentsDropDownList` passes in the department ID, which select the department specified in the drop-down list.
@ -133,7 +133,7 @@ When editing an instructor record, you may want to update the instructor's offic
Update the instructors Edit page model with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Edit1.cshtml.cs?name=snippet&highlight=20-23,32,39-)]
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Edit1.cshtml.cs?name=snippet&highlight=20-23,32,39-999)]
The preceding code:
@ -180,7 +180,7 @@ The `InstructorCoursesPageModel` is the base class you will use for the Edit and
Update the instructor Edit page model with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Edit.cshtml.cs?name=snippet&highlight=1,20-24,30,34,41-)]
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Edit.cshtml.cs?name=snippet&highlight=1,20-24,30,34,41-999)]
The preceding code handles office assignment changes.
@ -218,7 +218,7 @@ Test the instructor Create page.
Update the Delete page model with the following code:
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Delete.cshtml.cs?highlight=5,40-)]
[!code-csharp[Main](intro/samples/cu/Pages/Instructors/Delete.cshtml.cs?highlight=5,40-999)]
The preceding code makes the following changes:

View File

@ -22,7 +22,7 @@ This article provides instructions on how to diagnose an ASP.NET Core app startu
**502.5 Process Failure**
The worker process fails. The app doesn't start.
The [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) attempts to start the worker process but it fails to start. Examining the Application Event Log often helps troubleshoot this type of problem. Accessing the log is explained in the [Event log](#event-log) section.
The [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) attempts to start the worker process but it fails to start. Examining the Application Event Log often helps troubleshoot this type of problem. Accessing the log is explained in the [Application Event Log](#application-event-log) section.
The *502.5 Process Failure* error page is returned when a misconfigured app causes the worker process to fail:

View File

@ -0,0 +1,8 @@
This tutorial teaches ASP.NET Core MVC and Entity Framework Core with controllers and views. Razor Pages is a new alternative in ASP.NET Core 2.0, a page-based programming model that makes building web UI easier and more productive. We recommend the [Razor Pages](xref:data/ef-rp/intro) tutorial over the MVC version. The Razor Pages tutorial:
* Is easier to follow.
* Provides more EF Core best practices.
* Uses more efficient queries.
* Is more current with the lastest API.
* Covers more features.
* Is the preferred approach for new application development.

View File

@ -67,13 +67,13 @@ The `@model` directive specifies the type of the model passed to the Razor Page.
Consider the following code:
[!code-cshtml[Main](../../tutorials/razor-pages/razor-pages-start/snapshot_sample/RazorPagesMovie/Pages/Movies/Index.cshtml?range=1-6&highlight=4-)]
[!code-cshtml[Main](../../tutorials/razor-pages/razor-pages-start/snapshot_sample/RazorPagesMovie/Pages/Movies/Index.cshtml?range=1-6&highlight=4-999)]
The preceding highlighted code is an example of Razor transitioning into C#. The `{` and `}` characters enclose a block of C# code.
The `PageModel` base class has a `ViewData` dictionary property that can be used to add data that you want to pass to a View. You add objects into the `ViewData` dictionary using a key/value pattern. In the preceding sample, the "Title" property is added to the `ViewData` dictionary. The "Title" property is used in the *Pages/_Layout.cshtml* file. The following markup shows the first few lines of the *Pages/_Layout.cshtml* file.
[!code-cshtml[Main](../../tutorials/razor-pages/razor-pages-start/snapshot_sample/RazorPagesMovie/Pages/NU/_Layout1.cshtml?highlight=6-)]
[!code-cshtml[Main](../../tutorials/razor-pages/razor-pages-start/snapshot_sample/RazorPagesMovie/Pages/NU/_Layout1.cshtml?highlight=6-999)]
The line `@*Markup removed for brevity.*@` is a Razor comment. Unlike HTML comments (`<!-- -->`), Razor comments are not sent to the client.

View File

@ -55,7 +55,7 @@ The HTML `<form>` tag uses the [Form Tag Helper](xref:mvc/views/working-with-for
Add the the following highlighted properties to *Pages/Movies/Index.cshtml.cs*:
[!code-csharp[Main](../../tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie/Pages/Movies/Index.cshtml.cs?name=snippet_newProps&highlight=11-)]
[!code-csharp[Main](../../tutorials/razor-pages/razor-pages-start/sample/RazorPagesMovie/Pages/Movies/Index.cshtml.cs?name=snippet_newProps&highlight=11-999)]
The `SelectList Genres` contains the list of genres. This allows the user to select a genre from the list.

View File

@ -10,7 +10,7 @@ ms.technology: aspnet
ms.topic: article
uid: index
---
# Introduction to ASP.NET Core
# ASP.NET Core
By [Daniel Roth](https://github.com/danroth27), [Rick Anderson](https://twitter.com/RickAndMSFT), and [Shaun Luttin](https://twitter.com/dicshaunary)

View File

@ -221,7 +221,7 @@ You can also use the `[HtmlTargetElement]` to change the name of the targeted el
4. Add the following markup to the *About.cshtml* view. The highlighted markup displays the web site information.
[!code-html[Main](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml?highlight=1,12-)]
[!code-html[Main](authoring/sample/AuthoringTagHelpers/src/AuthoringTagHelpers/Views/Home/About.cshtml?highlight=1,12-999)]
>[!NOTE]
> In the Razor markup shown below:

View File

@ -37,7 +37,7 @@ In-memory caching is a *service* that's referenced from your app using [Dependen
Request the `IMemoryCache` instance in the constructor:
[!code-csharp[Main](memory/sample/WebCache/Controllers/HomeController.cs?name=snippet_ctor&highlight=3,5-)]
[!code-csharp[Main](memory/sample/WebCache/Controllers/HomeController.cs?name=snippet_ctor&highlight=3,5-999)]
`IMemoryCache` requires NuGet package "Microsoft.Extensions.Caching.Memory".

View File

@ -83,8 +83,6 @@ The correctly formatted URL for the QR Code is available in the:
* `AuthenticatorUri` property of the model.
* `data-url` property in the `qrCodeData` element.
Use `@Html.Raw` to access the model property in a view (otherwise the ampersands in the url will be double encoded and the label parameter of the QR Code will be ignored).
## TOTP client and server time skew
TOTP authentication depends on both the server and authenticator device having an accurate time. Tokens only last for 30 seconds. If TOTP 2FA logins are failing, check that the server time is accurate, and preferably synchronized to an accurate NTP service.

View File

@ -14,7 +14,7 @@ uid: security/authorization/claims
<a name="security-authorization-claims-based"></a>
When an identity is created it may be assigned one or more claims issued by a trusted party. A claim is name value pair that represents what the subject is, not what the subject can do. For example, you may have a driver's license, issued by a local driving license authority. Your driver's license has your date of birth on it. In this case the claim name would be `DateOfBirth`, the claim value would be your date of birth, for example `8th June 1970` and the issuer would be the driving license authority. Claims based authorization, at its simplest, checks the value of a claim and allows access to a resource based upon that value. For example if you want access to a night club the authorization process might be:
When an identity is created it may be assigned one or more claims issued by a trusted party. A claim is a name value pair that represents what the subject is, not what the subject can do. For example, you may have a driver's license, issued by a local driving license authority. Your driver's license has your date of birth on it. In this case the claim name would be `DateOfBirth`, the claim value would be your date of birth, for example `8th June 1970` and the issuer would be the driving license authority. Claims based authorization, at its simplest, checks the value of a claim and allows access to a resource based upon that value. For example if you want access to a night club the authorization process might be:
The door security officer would evaluate the value of your date of birth claim and whether they trust the issuer (the driving license authority) before granting you access.

View File

@ -61,7 +61,7 @@ This tutorial is advanced. You should be familiar with:
* [Authorization](xref:security/authorization/index)
* [Entity Framework Core](xref:data/ef-mvc/intro)
The ASP.NET Core 1.1 version of this tutorial is in [this](https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/secure-data) folder. The 1.1 ASP.NET Core sample is in the [samples](https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/secure-data/samples/final2).
See [this PDF file](https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/secure-data/asp.net_repo_pdf_1-16-18.pdf) for the ASP.NET Core MVC version. The ASP.NET Core 1.1 version of this tutorial is in [this](https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/secure-data) folder. The 1.1 ASP.NET Core sample is in the [samples](https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/secure-data/samples/final2).
## The starter and completed app
@ -81,7 +81,7 @@ The following sections have all the major steps to create the secure user data a
Use the ASP.NET [Identity](xref:security/authentication/identity) user ID to ensure users can edit their data, but not other users data. Add `OwnerID` and `ContactStatus` to the `Contact` model:
[!code-csharp[Main](secure-data/samples/final2/Models/Contact.cs?name=snippet1&highlight=5-6,16-)]
[!code-csharp[Main](secure-data/samples/final2/Models/Contact.cs?name=snippet1&highlight=5-6,16-999)]
`OwnerID` is the user's ID from the `AspNetUser` table in the [Identity](xref:security/authentication/identity) database. The `Status` field determines if a contact is viewable by general users.
@ -100,7 +100,7 @@ Add [IHostingEnvironment](/dotnet/api/microsoft.aspnetcore.hosting.ihostingenvir
In the `ConfigureServices` method of the *Startup.cs* file, add the [RequireHttpsAttribute](/aspnet/core/api/microsoft.aspnetcore.mvc.requirehttpsattribute) authorization filter:
[!code-csharp[Main](secure-data/samples/final2/Startup.cs?name=snippet_SSL&highlight=19-)]
[!code-csharp[Main](secure-data/samples/final2/Startup.cs?name=snippet_SSL&highlight=19-999)]
If you're using Visual Studio, enable SSL.
@ -112,7 +112,7 @@ To redirect HTTP requests to HTTPS, see [URL Rewriting Middleware](xref:fundamen
Set the default authentication policy to require users to be authenticated. You can opt out of authentication at the Razor Page, controller, or action method level with the `[AllowAnonymous]` attribute. Setting the default authentication policy to require users to be authenticated protects newly added Razor Pages and controllers. Having authentication required by default is safer than relying on new controllers and Razor Pages to include the `[Authorize]` attribute. Add the following to the `ConfigureServices` method of the *Startup.cs* file:
[!code-csharp[Main](secure-data/samples/final2/Startup.cs?name=snippet_defaultPolicy&highlight=31-)]
[!code-csharp[Main](secure-data/samples/final2/Startup.cs?name=snippet_defaultPolicy&highlight=31-999)]
Add [AllowAnonymous](/dotnet/api/microsoft.aspnetcore.authorization.allowanonymousattribute) to the Index, About, and Contact pages so anonymous users can get information about the site before they register.
@ -173,7 +173,7 @@ Create a `ContactAdministratorsAuthorizationHandler` class in the *Authorization
Services using Entity Framework Core must be registered for [dependency injection](xref:fundamentals/dependency-injection) using [AddScoped](/aspnet/core/api/microsoft.extensions.dependencyinjection.servicecollectionserviceextensions). The `ContactIsOwnerAuthorizationHandler` uses ASP.NET Core [Identity](xref:security/authentication/identity), which is built on Entity Framework Core. Register the handlers with the service collection so they're available to the `ContactsController` through [dependency injection](xref:fundamentals/dependency-injection). Add the following code to the end of `ConfigureServices`:
[!code-csharp[Main](secure-data/samples/final2/Startup.cs?name=ConfigureServices&highlight=41-)]
[!code-csharp[Main](secure-data/samples/final2/Startup.cs?name=ConfigureServices&highlight=41-999)]
`ContactAdministratorsAuthorizationHandler` and `ContactManagerAuthorizationHandler` are added as singletons. They're singletons because they don't use EF and all the information needed is in the `Context` parameter of the `HandleRequirementAsync` method.
@ -242,7 +242,7 @@ The preceding markup adds several `using` statements.
Update the **Edit** and **Delete** links in *Pages/Contacts/Index.cshtml* so they're only rendered for users with the appropriate permissions:
[!code-cshtml[Main](secure-data/samples/final2/Pages/Contacts/Index.cshtml?highlight=34-36,64-)]
[!code-cshtml[Main](secure-data/samples/final2/Pages/Contacts/Index.cshtml?highlight=34-36,64-999)]
> [!WARNING]
> Hiding links from users that don't have permission to change data doesn't secure the app. Hiding links makes the app more user-friendly by displaying only valid links. Users can hack the generated URLs to invoke edit and delete operations on data they don't own. The Razor Page or controller must enforce access checks to secure the data.
@ -251,7 +251,7 @@ Update the **Edit** and **Delete** links in *Pages/Contacts/Index.cshtml* so the
Update the details view so managers can approve or reject contacts:
[!code-cshtml[Main](secure-data/samples/final2/Pages/Contacts/Details.cshtml?range=48-)]
[!code-cshtml[Main](secure-data/samples/final2/Pages/Contacts/Details.cshtml?range=48-999)]
Update the details page model:

View File

@ -25,11 +25,11 @@ The [RequireHttpsAttribute](https://docs.microsoft.com/aspnet/core/api/microsoft
Add the following code to `ConfigureServices` in `Startup`:
[!code-csharp[Main](authentication/accconfirm/sample/WebApp1/Startup.cs?name=snippet2&highlight=4-)]
[!code-csharp[Main](authentication/accconfirm/sample/WebApp1/Startup.cs?name=snippet2&highlight=4-999)]
The highlighted code above requires all requests use `HTTPS`, therefore HTTP requests are ignored. The following highlighted code redirects all HTTP requests to HTTPS:
[!code-csharp[Main](authentication/accconfirm/sample/WebApp1/Startup.cs?name=snippet_AddRedirectToHttps&highlight=7-)]
[!code-csharp[Main](authentication/accconfirm/sample/WebApp1/Startup.cs?name=snippet_AddRedirectToHttps&highlight=7-999)]
See [URL Rewriting Middleware](xref:fundamentals/url-rewriting) for more information.

View File

@ -27,6 +27,35 @@
### [Add validation](tutorials/first-mvc-app/validation.md)
### [Examine the Details and Delete methods](tutorials/first-mvc-app/details.md)
## [Build Web APIs](mvc/web-api/index.md)
### [Create a Web API on Mac](xref:tutorials/first-web-api-mac)
### [ASP.NET Core Web API help pages using Swagger](tutorials/web-api-help-pages-using-swagger.md)
### [Create backend services for native mobile apps](mobile/native-mobile-backend.md)
## [Data access - with EF Core](xref:data/index)
### [Data access - with Razor Pages and EF Core](xref:data/ef-rp/index)
#### [Get started](xref:data/ef-rp/intro)
#### [Create, Read, Update, and Delete operations](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)
### [Data access - MVC with EF Core](data/ef-mvc/index.md)
#### [Get started](data/ef-mvc/intro.md)
#### [Create, Read, Update, and Delete operations](data/ef-mvc/crud.md)
#### [Sort, filter, page, and group](data/ef-mvc/sort-filter-page.md)
#### [Migrations](data/ef-mvc/migrations.md)
#### [Create a complex data model](data/ef-mvc/complex-data-model.md)
#### [Read related data](data/ef-mvc/read-related-data.md)
#### [Update related data](data/ef-mvc/update-related-data.md)
#### [Handle concurrency conflicts](data/ef-mvc/concurrency.md)
#### [Inheritance](data/ef-mvc/inheritance.md)
#### [Advanced topics](data/ef-mvc/advanced.md)
## [Cross platform tutorials](xref:tutorials/xplat)
### [Razor Pages web app on a Mac](xref:tutorials/razor-pages-mac/index)
#### [Getting started with Razor Pages](xref:tutorials/razor-pages-mac/razor-pages-start)
@ -71,33 +100,7 @@
### [Web API with Visual Studio for Mac](xref:tutorials/first-web-api-mac)
### [Web API with Visual Studio Code](xref:tutorials/web-api-vsc)
## [Data access - Razor Pages with EF Core](xref:data/index)
### [Get started](xref:data/ef-rp/intro)
### [Create, Read, Update, and Delete operations](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)
## [Data access - MVC with EF Core](data/ef-mvc/index.md)
### [Get started](data/ef-mvc/intro.md)
### [Create, Read, Update, and Delete operations](data/ef-mvc/crud.md)
### [Sort, filter, page, and group](data/ef-mvc/sort-filter-page.md)
### [Migrations](data/ef-mvc/migrations.md)
### [Create a complex data model](data/ef-mvc/complex-data-model.md)
### [Read related data](data/ef-mvc/read-related-data.md)
### [Update related data](data/ef-mvc/update-related-data.md)
### [Handle concurrency conflicts](data/ef-mvc/concurrency.md)
### [Inheritance](data/ef-mvc/inheritance.md)
### [Advanced topics](data/ef-mvc/advanced.md)
## [Create backend services for mobile apps](mobile/native-mobile-backend.md)
## [Build Web APIs](mvc/web-api/index.md)
## [Create a Web API](xref:tutorials/first-web-api-mac)
### [ASP.NET Core Web API help pages using Swagger](tutorials/web-api-help-pages-using-swagger.md)
### [Create backend services for native mobile apps](mobile/native-mobile-backend.md)
# [Fundamentals](fundamentals/index.md)
## [Application startup](fundamentals/startup.md)
@ -178,9 +181,9 @@
## [Snapshot debugging](/azure/application-insights/app-insights-snapshot-debugger)
## [Snapshot debugging in Visual Studio](/visualstudio/debugger/debug-live-azure-applications)
# [Data access and storage](data/index.md)
## [Get started with Razor Pages and Entity Framework Core using Visual Studio](xref:data/ef-rp/intro)
## [Get started with ASP.NET Core and Entity Framework Core using Visual Studio](data/ef-mvc/index.md)
# [Data access with EF Core and Azure](data/index.md)
## [Get started with Razor Pages and EF Core using Visual Studio](xref:data/ef-rp/intro)
## [Get started with ASP.NET Core and EF Core using Visual Studio](data/ef-mvc/index.md)
## [ASP.NET Core with EF Core - new database](https://docs.microsoft.com/ef/core/get-started/aspnetcore/new-db)
## [ASP.NET Core with EF Core - existing database](https://docs.microsoft.com/ef/core/get-started/aspnetcore/existing-db)
## [Get started with ASP.NET Core and Entity Framework 6](data/entity-framework-6.md)

View File

@ -47,9 +47,10 @@ The following step-by-step guides for developing ASP.NET Core applications are a
* [Create backend web services for native mobile apps](../mobile/native-mobile-backend.md)
## Data access and storage
* [Get started with ASP.NET Core and Entity Framework Core using Visual Studio](../data/ef-mvc/index.md)
* [ASP.NET Core with EF Core - new database](https://docs.microsoft.com/ef/core/get-started/aspnetcore/new-db)
* [ASP.NET Core with EF Core - existing database](https://docs.microsoft.com/ef/core/get-started/aspnetcore/existing-db)
* [Get started with Razor Pages and EF Core using Visual Studio](xref:data/ef-rp/intro)
* [Get started with ASP.NET Core MVC and EF Core using Visual Studio](../data/ef-mvc/index.md)
* [ASP.NET Core MVC with EF Core - new database](https://docs.microsoft.com/ef/core/get-started/aspnetcore/new-db)
* [ASP.NET Core MVC with EF Core - existing database](https://docs.microsoft.com/ef/core/get-started/aspnetcore/existing-db)
## Authentication and authorization
* [Enable authentication using Facebook, Google, and other external providers](../security/authentication/social/index.md)

View File

@ -65,7 +65,7 @@ The HTML `<form>` tag uses the [Form Tag Helper](xref:mvc/views/working-with-for
Add the the following highlighted properties to *Pages/Movies/Index.cshtml.cs*:
[!code-csharp[Main](razor-pages-start/sample/RazorPagesMovie/Pages/Movies/Index.cshtml.cs?name=snippet_newProps&highlight=11-)]
[!code-csharp[Main](razor-pages-start/sample/RazorPagesMovie/Pages/Movies/Index.cshtml.cs?name=snippet_newProps&highlight=11-999)]
The `SelectList Genres` contains the list of genres. This allows the user to select a genre from the list.

View File

@ -1,22 +1,20 @@
---
title: ASP.NET Core Web API Help Pages using Swagger
title: ASP.NET Core Web API help pages using Swagger
author: spboyer
description: This tutorial provides a walkthrough of adding Swagger to generate documentation and help pages for a Web API application.
manager: wpickett
ms.author: spboyer
ms.date: 09/01/2017
ms.date: 02/02/2018
ms.prod: asp.net-core
ms.technology: aspnet
ms.topic: article
uid: tutorials/web-api-help-pages-using-swagger
---
# ASP.NET Core Web API Help Pages using Swagger
<a name="web-api-help-pages-using-swagger"></a>
# ASP.NET Core Web API help pages using Swagger
By [Shayne Boyer](https://twitter.com/spboyer) and [Scott Addie](https://twitter.com/Scott_Addie)
Understanding the various methods of an API can be a challenge for a developer when building a consuming application.
Understanding the various methods of an API can be a challenge for a developer when building a consuming app.
Generating good documentation and help pages for your Web API, using [Swagger](https://swagger.io/) with the .NET Core implementation [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore), is as easy as adding a couple of NuGet packages and modifying the *Startup.cs*.
@ -26,7 +24,7 @@ Generating good documentation and help pages for your Web API, using [Swagger](h
This tutorial builds on the sample on [Building Your First Web API with ASP.NET Core MVC and Visual Studio](xref:tutorials/first-web-api). If you'd like to follow along, download the sample at [https://github.com/aspnet/Docs/tree/master/aspnetcore/tutorials/first-web-api/sample](https://github.com/aspnet/Docs/tree/master/aspnetcore/tutorials/first-web-api/sample).
## Getting Started
## Get started
There are three main components to Swashbuckle:
@ -36,7 +34,7 @@ There are three main components to Swashbuckle:
* `Swashbuckle.AspNetCore.SwaggerUI`: an embedded version of the Swagger UI tool which interprets Swagger JSON to build a rich, customizable experience for describing the Web API functionality. It includes built-in test harnesses for the public methods.
## NuGet Packages
## NuGet packages
Swashbuckle can be added with the following approaches:
@ -84,7 +82,7 @@ dotnet add TodoApi.csproj package Swashbuckle.AspNetCore
Add the Swagger generator to the services collection in the `ConfigureServices` method of *Startup.cs*:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Startup2.cs?name=snippet_ConfigureServices&highlight=7-10)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Startup2.cs?name=snippet_ConfigureServices&highlight=7-10)]
Add the following using statement for the `Info` class:
@ -94,11 +92,12 @@ using Swashbuckle.AspNetCore.Swagger;
In the `Configure` method of *Startup.cs*, enable the middleware for serving the generated JSON document and the SwaggerUI:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Startup2.cs?name=snippet_Configure&highlight=4,7-10)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Startup2.cs?name=snippet_Configure&highlight=4,7-10)]
Launch the app, and navigate to `http://localhost:<random_port>/swagger/v1/swagger.json`. The generated document describing the endpoints appears.
**Note:** Microsoft Edge, Google Chrome, and Firefox display JSON documents natively. There are extensions for Chrome that format the document for easier reading. *The following example is reduced for brevity.*
> [!NOTE]
> Microsoft Edge, Google Chrome, and Firefox display JSON documents natively. There are extensions for Chrome that format the document for easier reading. *The following example is reduced for brevity.*
```json
{
@ -177,21 +176,21 @@ Each public action method in `TodoController` can be tested from the UI. Click a
![Example Swagger GET test](web-api-help-pages-using-swagger/_static/get-try-it-out.png)
## Customization & Extensibility
## Customize & extend
Swagger provides options for documenting the object model and customizing the UI to match your theme.
### API Info and Description
### API info and description
The configuration action passed to the `AddSwaggerGen` method can be used to add information such as the author, license, and description:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Startup.cs?range=20-30,36)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Startup.cs?range=20-30,36)]
The following image depicts the Swagger UI displaying the version information:
![Swagger UI with version information: description, author, and see more link](web-api-help-pages-using-swagger/_static/custom-info.png)
### XML Comments
### XML comments
XML comments can be enabled with the following approaches:
@ -213,7 +212,7 @@ XML comments can be enabled with the following approaches:
Manually add the following snippet to the *.csproj* file:
[!code-xml[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/TodoApi.csproj?range=7-9)]
[!code-xml[](web-api-help-pages-using-swagger/sample/TodoApi/TodoApi.csproj?range=8-9,11)]
# [.NET Core CLI](#tab/netcore-cli)
@ -221,17 +220,25 @@ See Visual Studio Code.
---
Enabling XML comments provides debug information for undocumented public types and members. Undocumented types and members are indicated by the warning message: *Missing XML comment for publicly visible type or member*.
Enabling XML comments provides debug information for undocumented public types and members. Undocumented types and members are indicated by the warning message. For example, the following message indicates a violation of warning code 1591:
```
warning CS1591: Missing XML comment for publicly visible type or member 'TodoController.GetAll()'
```
Suppress warnings by defining a semicolon-delimited list of warning codes to ignore in the *.csproj* file:
[!code-xml[](web-api-help-pages-using-swagger/sample/TodoApi/TodoApi.csproj?name=snippet_SuppressWarnings&highlight=3)]
Configure Swagger to use the generated XML file. For Linux or non-Windows operating systems, file names and paths can be case sensitive. For example, a *ToDoApi.XML* file would be found on Windows but not CentOS.
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Startup.cs?name=snippet_ConfigureServices&highlight=20-22)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Startup.cs?name=snippet_ConfigureServices&highlight=20-22)]
In the preceding code, `ApplicationBasePath` gets the base path of the app. The base path is used to locate the XML comments file. *TodoApi.xml* only works for this example, since the name of the generated XML comments file is based on the application name.
In the preceding code, `ApplicationBasePath` gets the base path of the app. The base path is used to locate the XML comments file. *TodoApi.xml* only works for this example, since the name of the generated XML comments file is based on the app name.
Adding the triple-slash comments to the method enhances the Swagger UI by adding the description to the section header:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Delete&highlight=2)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Delete&highlight=2)]
![Swagger UI showing XML comment 'Deletes a specific TodoItem.' for the DELETE method](web-api-help-pages-using-swagger/_static/triple-slash-comments.png)
@ -266,19 +273,19 @@ The UI is driven by the generated JSON file, which also contains these comments:
Add a [<remarks>](https://docs.microsoft.com/dotnet/csharp/programming-guide/xmldoc/remarks) tag to the `Create` action method documentation. It supplements information specified in the `<summary>` tag and provides a more robust Swagger UI. The `<remarks>` tag content can consist of text, JSON, or XML.
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Create&highlight=4-14)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Create&highlight=4-14)]
Notice the UI enhancements with these additional comments.
![Swagger UI with additional comments shown](web-api-help-pages-using-swagger/_static/xml-comments-extended.png)
### Data Annotations
### Data annotations
Decorate the model with attributes, found in `System.ComponentModel.DataAnnotations`, to help drive the Swagger UI components.
Add the `[Required]` attribute to the `Name` property of the `TodoItem` class:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Models/TodoItem.cs?highlight=10)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Models/TodoItem.cs?highlight=10)]
The presence of this attribute changes the UI behavior and alters the underlying JSON schema:
@ -308,7 +315,7 @@ The presence of this attribute changes the UI behavior and alters the underlying
Add the `[Produces("application/json")]` attribute to the API controller. Its purpose is to declare that the controller's actions support a return a content type of *application/json*:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_TodoController&highlight=3)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_TodoController&highlight=3)]
The **Response Content Type** drop-down selects this content type as the default for the controller's GET actions:
@ -316,19 +323,19 @@ The **Response Content Type** drop-down selects this content type as the default
As the usage of data annotations in the Web API increases, the UI and API help pages become more descriptive and useful.
### Describing Response Types
### Describe response types
Consuming developers are most concerned with what is returned &mdash; specifically response types and error codes (if not standard). These are handled in the XML comments and data annotations.
The `Create` action returns `201 Created` on success or `400 Bad Request` when the posted request body is null. Without proper documentation in the Swagger UI, the consumer lacks knowledge of these expected outcomes. That problem is fixed by adding the highlighted lines in the following example:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Create&highlight=17,18,20,21)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Create&highlight=17,18,20,21)]
The Swagger UI now clearly documents the expected HTTP response codes:
![Swagger UI showing POST Response Class description 'Returns the newly created Todo item' and '400 - If the item is null' for status code and reason under Response Messages](web-api-help-pages-using-swagger/_static/data-annotations-response-types.png)
### Customizing the UI
### Customize the UI
The stock UI is both functional and presentable; however, when building documentation pages for your API, you want it to represent your brand or theme. Accomplishing that task with the Swashbuckle components requires adding the resources to serve static files and then building the folder structure to host those files.
@ -340,7 +347,7 @@ If targeting .NET Framework, add the `Microsoft.AspNetCore.StaticFiles` NuGet pa
Enable the static files middleware:
[!code-csharp[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/Startup.cs?name=snippet_Configure&highlight=3)]
[!code-csharp[](web-api-help-pages-using-swagger/sample/TodoApi/Startup.cs?name=snippet_Configure&highlight=3)]
Acquire the contents of the *dist* folder from the [Swagger UI GitHub repository](https://github.com/swagger-api/swagger-ui/tree/2.x/dist). This folder contains the necessary assets for the Swagger UI page.
@ -348,11 +355,11 @@ Create a *wwwroot/swagger/ui* folder, and copy into it the contents of the *dist
Create a *wwwroot/swagger/ui/css/custom.css* file with the following CSS to customize the page header:
[!code-css[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/wwwroot/swagger/ui/css/custom.css)]
[!code-css[](web-api-help-pages-using-swagger/sample/TodoApi/wwwroot/swagger/ui/css/custom.css)]
Reference *custom.css* in the *index.html* file:
[!code-html[Main](../tutorials/web-api-help-pages-using-swagger/sample/TodoApi/wwwroot/swagger/ui/index.html?range=14)]
[!code-html[](web-api-help-pages-using-swagger/sample/TodoApi/wwwroot/swagger/ui/index.html?range=14)]
Browse to the *index.html* page at `http://localhost:<random_port>/swagger/ui/index.html`. Enter `http://localhost:<random_port>/swagger/v1/swagger.json` in the header's textbox, and click the **Explore** button. The resulting page looks as follows:

View File

@ -1,10 +1,9 @@
using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.PlatformAbstractions;
using Swashbuckle.AspNetCore.Swagger;
using System;
using System.IO;
using TodoApi.Models;
namespace TodoApi

View File

@ -4,9 +4,12 @@
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<!-- <snippet_SuppressWarnings> -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>bin\Debug\netcoreapp2.0\TodoApi.xml</DocumentationFile>
<NoWarn>1701;1702;1705;1591</NoWarn>
</PropertyGroup>
<!-- </snippet_SuppressWarnings> -->
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />