From d2f705f7a8ef2c1a940f590e4de188621fd48d2a Mon Sep 17 00:00:00 2001
From: Scott Addie
Date: Wed, 13 Sep 2017 11:06:58 -0500
Subject: [PATCH] Updates to Razor Pages intro doc (#4262)
* Updates to Razor Pages intro doc
* More updates
* Remove @functions conversion reference
* Remove all @functions references and code
* Change code snippet type to cshtml
---
aspnetcore/mvc/razor-pages/index.md | 63 +++++++---------
.../RazorPagesContacts/Data/AppDbContext.cs | 3 +-
.../RazorPagesContacts/Data/Customer.cs | 2 +-
.../RazorPagesContacts/Pages/Create.cshtml.cs | 6 +-
.../Pages/CreateCombined.cshtml | 35 ---------
.../RazorPagesContacts/Pages/Edit.cshtml.cs | 2 +-
.../Pages/IndexCombined.cshtml | 72 -------------------
.../sample/RazorPagesContacts/Program.cs | 14 ++--
.../RazorPagesContacts.csproj | 7 +-
.../sample/RazorPagesContacts/Startup.cs | 2 +-
.../RazorPagesContacts/StartupAdvanced.cs | 2 +-
.../sample/RazorPagesContacts/StartupDebug.cs | 4 +-
.../RazorPagesContacts2/Data/AppDbContext.cs | 3 +-
.../RazorPagesContacts2/Data/Customer.cs | 2 +-
.../Pages/Customers/CreateDot.cshtml.cs | 4 +-
.../Pages/Customers/CreateTempData.cshtml.cs | 1 -
.../Pages/Customers/Edit.cshtml.cs | 4 +-
.../Pages/Customers/Index.cshtml.cs | 1 -
.../Pages/Reports/Class.cs | 11 ---
.../Pages/Reports/Test.cshtml | 28 --------
.../Pages/Reports/Time.cshtml | 20 ------
.../Pages/Reports/TimeTempData.cshtml | 22 ------
.../sample/RazorPagesContacts2/Program.cs | 18 +++--
.../RazorPagesContacts2.csproj | 7 +-
.../sample/RazorPagesContacts2/Startup.cs | 4 +-
.../Pages/Customers/Namespace2.cshtml.cs | 2 +-
.../sample/RazorPagesIntro/Pages/Index.cshtml | 20 +-----
.../RazorPagesIntro/Pages/Index2.cshtml | 3 +-
.../RazorPagesIntro/Pages/Index2.cshtml.cs | 3 +-
.../index/sample/RazorPagesIntro/Program.cs | 18 +++--
.../RazorPagesIntro/RazorPagesIntro.csproj | 6 +-
.../index/sample/RazorPagesIntro/Startup.cs | 4 +-
32 files changed, 74 insertions(+), 319 deletions(-)
delete mode 100644 aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/CreateCombined.cshtml
delete mode 100644 aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/IndexCombined.cshtml
delete mode 100644 aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts2/Pages/Reports/Class.cs
delete mode 100644 aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts2/Pages/Reports/Test.cshtml
delete mode 100644 aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts2/Pages/Reports/Time.cshtml
delete mode 100644 aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts2/Pages/Reports/TimeTempData.cshtml
diff --git a/aspnetcore/mvc/razor-pages/index.md b/aspnetcore/mvc/razor-pages/index.md
index 65f96ea3bcde..e896e9bd3872 100644
--- a/aspnetcore/mvc/razor-pages/index.md
+++ b/aspnetcore/mvc/razor-pages/index.md
@@ -1,11 +1,11 @@
---
title: Introduction to Razor Pages in ASP.NET Core
author: Rick-Anderson
-description: Overview of Razor Pages in ASP.NET Core
-keywords: ASP.NET Core, Razor Pages
+description: This doc provides an overview of using Razor Pages in ASP.NET Core to ease the development of page-focused scenarios.
+keywords: ASP.NET Core,Razor Pages
ms.author: riande
manager: wpickett
-ms.date: 08/15/2017
+ms.date: 09/12/2017
ms.topic: get-started-article
ms.technology: aspnet
ms.prod: asp.net-core
@@ -25,7 +25,7 @@ If you're looking for a tutorial that uses the Model-View-Controller approach, s
Install [.NET Core](https://www.microsoft.com/net/core) 2.0.0 or later.
-If you're using Visual Studio, install [Visual Studio](https://www.visualstudio.com/vs/) 15.3 or later with the following workloads:
+If you're using Visual Studio, install [Visual Studio](https://www.visualstudio.com/vs/) 2017 version 15.3 or later with the following workloads:
* **ASP.NET and web development**
* **.NET Core cross-platform development**
@@ -58,27 +58,25 @@ Run `dotnet new razor` from the command line.
Razor Pages is enabled in *Startup.cs*:
-[!code-cs[main](index/sample/RazorPagesIntro/Startup.cs?name=Startup)]
+[!code-cs[main](index/sample/RazorPagesIntro/Startup.cs?name=snippet_Startup)]
Consider a basic page:
[!code-cshtml[main](index/sample/RazorPagesIntro/Pages/Index.cshtml)]
-The preceding code looks a lot like a Razor view file. What makes it different is the `@page` directive. `@page` makes the file into an MVC action - which means that it handles requests directly, without going through a controller. `@page` must be the first Razor directive on a page. `@page` affects the behavior of other Razor constructs. The [@functions](xref:mvc/views/razor#functions) directive enables function-level content.
+The preceding code looks a lot like a Razor view file. What makes it different is the `@page` directive. `@page` makes the file into an MVC action - which means that it handles requests directly, without going through a controller. `@page` must be the first Razor directive on a page. `@page` affects the behavior of other Razor constructs.
-A similar page, with the `PageModel` in a separate file, is shown in the following two files. The *Pages/Index2.cshtml* file:
+A similar page, using a `PageModel` class, is shown in the following two files. The *Pages/Index2.cshtml* file:
[!code-cshtml[main](index/sample/RazorPagesIntro/Pages/Index2.cshtml)]
-The *Pages/Index2.cshtml.cs* 'code-behind' file:
+The *Pages/Index2.cshtml.cs* "code-behind" file:
[!code-cs[main](index/sample/RazorPagesIntro/Pages/Index2.cshtml.cs)]
By convention, the `PageModel` class file has the same name as the Razor Page file with *.cs* appended. For example, the previous Razor Page is *Pages/Index2.cshtml*. The file containing the `PageModel` class is named *Pages/Index2.cshtml.cs*.
-For simple pages, mixing the `PageModel` class with the Razor markup is fine. For more complex code, it's a best practice to keep the page model code separate.
-
The associations of URL paths to pages are determined by the page's location in the file system. The following table shows a Razor Page path and the matching URL:
| File name and path | matching URL |
@@ -86,7 +84,7 @@ The associations of URL paths to pages are determined by the page's location in
| */Pages/Index.cshtml* | `/` or `/Index` |
| */Pages/Contact.cshtml* | `/Contact` |
| */Pages/Store/Contact.cshtml* | `/Store/Contact` |
-| */Pages/Store/Index.cshtml* | `/Store` or `/Store/Index` |
+| */Pages/Store/Index.cshtml* | `/Store` or `/Store/Index` |
Notes:
@@ -111,9 +109,9 @@ The *Pages/Create.cshtml* view file:
The *Pages/Create.cshtml.cs* code-behind file for the view:
-[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=ALL)]
+[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=snippet_ALL)]
-By convention, the `PageModel` class is called `Model` and is in the same namespace as the page. Not much change is needed to convert from a page using `@functions` to define handlers and a page using a `PageModel` class.
+By convention, the `PageModel` class is called `Model` and is in the same namespace as the page.
Using a `PageModel` code-behind file supports unit testing, but requires you to write an explicit constructor and class. Pages without `PageModel` code-behind files support runtime compilation, which can be an advantage in development.
@@ -126,7 +124,7 @@ The `Async` naming suffix is optional but is often used by convention for asynch
The previous `OnPostAsync` method:
-[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=OnPostAsync)]
+[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=snippet_OnPostAsync)]
The basic flow of `OnPostAsync`:
@@ -141,19 +139,10 @@ When the submitted form has validation errors (that are passed to the server), t
The `Customer` property uses `[BindProperty]` attribute to opt in to model binding.
-[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=PageModel&highlight=10-11)]
+[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=snippet_PageModel&highlight=10-11)]
Razor Pages, by default, bind properties only with non-GET verbs. Binding to properties can reduce the amount of code you have to write. Binding reduces code by using the same property to render form fields (``) and accept the input.
-The following code shows the combined version of the create page:
-
-[!code-cshtml[main](index/sample/RazorPagesContacts/Pages/CreateCombined.cshtml)]
-
-Rather than using `@model`, we're taking advantage of a new feature for Pages. By default, the generated `Page`-derived class *is* the model. Using a *view model* with Razor views is a best practice. With Pages, you get a view model *automatically*.
-
-The main change is replacing constructor injection with injected (`@inject`) properties. This page uses [@inject](xref:mvc/views/razor#inject) for [constructor dependency injection](xref:mvc/controllers/dependency-injection#constructor-injection). The `@inject` statement generates and initializes the `Db` property that is used in `OnPostAsync`. Injected (`@inject`) properties are set before handler methods run.
-
-
The home page (*Index.cshtml*):
[!code-cshtml[main](index/sample/RazorPagesContacts/Pages/Index.cshtml)]
@@ -164,7 +153,7 @@ The code behind *Index.cshtml.cs* file:
The *Index.cshtml* file contains the following markup to create an edit link for each contact:
-```html
+```cshtml
edit
```
@@ -210,7 +199,7 @@ The [Layout](xref:mvc/views/layout#specifying-a-layout) property is set in *Page
[!code-cshtml[main](index/sample/RazorPagesContacts2/Pages/_ViewStart.cshtml)]
-Note: The layout is in the *Pages* folder. Pages look for other views (layouts, templates, partials) hierarchically, starting in the same folder as the current page. A layout in the *Pages* folder can be used from any Razor page under the *Pages* folder.
+**Note:** The layout is in the *Pages* folder. Pages look for other views (layouts, templates, partials) hierarchically, starting in the same folder as the current page. A layout in the *Pages* folder can be used from any Razor page under the *Pages* folder.
We recommend you **not** put the layout file in the *Views/Shared* folder. *Views/Shared* is an MVC views pattern. Razor Pages are meant to rely on folder hierarchy, not path conventions.
@@ -234,7 +223,7 @@ When the `@namespace` directive is contained in *_ViewImports.cshtml*, the speci
For example, the code behind file *Pages/Customers/Edit.cshtml.cs* explicitly sets the namespace:
-[!code-cs[main](index/sample/RazorPagesContacts2/Pages/Customers/Edit.cshtml.cs?name=namespace)]
+[!code-cs[main](index/sample/RazorPagesContacts2/Pages/Customers/Edit.cshtml.cs?name=snippet_namespace)]
The *Pages/_ViewImports.cshtml* file sets the following namespace:
@@ -242,15 +231,13 @@ The *Pages/_ViewImports.cshtml* file sets the following namespace:
The generated namespace for the *Pages/Customers/Edit.cshtml* Razor Page is the same as the code behind file. The `@namespace` directive was designed so the C# classes added to a project and pages-generated code *just work* without having to add an `@using` directive for the code behind file.
-Note: `@namespace` also works with conventional Razor views.
+**Note:** `@namespace` also works with conventional Razor views.
The original *Pages/Create.cshtml* view file:
[!code-cshtml[main](index/sample/RazorPagesContacts/Pages/Create.cshtml?highlight=2)]
-The updated page:
-
-The *Pages/Create.cshtml* view file:
+The updated *Pages/Create.cshtml* view file:
[!code-cshtml[main](index/sample/RazorPagesContacts2/Pages/Customers/Create.cshtml?highlight=2)]
@@ -262,9 +249,9 @@ The [Razor Pages starter project](#rpvs17) contains the *Pages/_ValidationScript
The `Create` page, shown previously, uses `RedirectToPage`:
-[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=OnPostAsync&highlight=10)]
+[!code-cs[main](index/sample/RazorPagesContacts/Pages/Create.cshtml.cs?name=snippet_OnPostAsync&highlight=10)]
-The app has the following file/folder structure
+The app has the following file/folder structure:
* */Pages*
@@ -302,8 +289,9 @@ ASP.NET Core exposes the [TempData](https://docs.microsoft.com/aspnet/core/api/m
The `[TempData]` attribute is new in ASP.NET Core 2.0 and is supported on controllers and pages.
-The following code sets the value of `Message` using `TempData`.
-[!code-cs[main](index/sample/RazorPagesContacts2/Pages/Customers/CreateDot.cshtml.cs?highlight=10-11,27-28&name=snippetTemp)]
+The following code sets the value of `Message` using `TempData`:
+
+[!code-cs[main](index/sample/RazorPagesContacts2/Pages/Customers/CreateDot.cshtml.cs?highlight=10-11,25&name=snippet_Temp)]
The following markup in the *Pages/Customers/Index.cshtml* file displays the value of `Message` using `TempData`.
@@ -347,7 +335,6 @@ If you don't like the query string `?handler=JoinList` in the URL, you can chang
[!code-cshtml[main](index/sample/RazorPagesContacts2/Pages/Customers/CreateRoute.cshtml?highlight=1)]
-
The preceding route puts the handler name in the URL path instead of the query string. The `?` following `handler` means the route parameter is optional.
You can use `@page` to add additional segments and parameters to a page's route. Whatever's there is **appended** to the default route of the page. Using an absolute or virtual path to change the page's route (like `"~/Some/Other/Path"`) is not supported.
@@ -356,7 +343,7 @@ You can use `@page` to add additional segments and parameters to a page's route.
To configure advanced options, use the extension method `AddRazorPagesOptions` on the MVC builder:
-[!code-cs[main](index/sample/RazorPagesContacts/StartupAdvanced.cs?name=snippet1)]
+[!code-cs[main](index/sample/RazorPagesContacts/StartupAdvanced.cs?name=snippet_1)]
Currently you can use the `RazorPagesOptions` to set the root directory for pages, or add application model conventions for pages. We hope to enable more extensibility this way in the future.
@@ -364,4 +351,4 @@ To precompile views, see [Razor view compilation](xref:mvc/views/view-compilatio
[Download or view sample code](https://github.com/aspnet/Docs/tree/master/aspnetcore/mvc/razor-pages/index/sample).
-See [Getting started with Razor Pages in ASP.NET Core](xref:tutorials/razor-pages/razor-pages-start), which builds on this introduction.
+See [Getting started with Razor Pages in ASP.NET Core](xref:tutorials/razor-pages/razor-pages-start), which builds on this introduction.
\ No newline at end of file
diff --git a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/AppDbContext.cs b/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/AppDbContext.cs
index 841acfd0b150..50f9ddaf0cca 100644
--- a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/AppDbContext.cs
+++ b/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/AppDbContext.cs
@@ -7,9 +7,8 @@ public class AppDbContext : DbContext
public AppDbContext(DbContextOptions options)
: base(options)
{
-
}
public DbSet Customers { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/Customer.cs b/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/Customer.cs
index b247c4427280..8f6ca96dd006 100644
--- a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/Customer.cs
+++ b/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Data/Customer.cs
@@ -9,4 +9,4 @@ public class Customer
[Required, StringLength(100)]
public string Name { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/Create.cshtml.cs b/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/Create.cshtml.cs
index 3b78e7c184eb..0bb1c526f017 100644
--- a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/Create.cshtml.cs
+++ b/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/Create.cshtml.cs
@@ -1,4 +1,4 @@
-#region ALL
+#region snippet_ALL
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -6,7 +6,7 @@
namespace RazorPagesContacts.Pages
{
- #region PageModel
+ #region snippet_PageModel
public class CreateModel : PageModel
{
private readonly AppDbContext _db;
@@ -19,7 +19,7 @@ public CreateModel(AppDbContext db)
[BindProperty]
public Customer Customer { get; set; }
- #region OnPostAsync
+ #region snippet_OnPostAsync
public async Task OnPostAsync()
{
if (!ModelState.IsValid)
diff --git a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/CreateCombined.cshtml b/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/CreateCombined.cshtml
deleted file mode 100644
index 222a63150469..000000000000
--- a/aspnetcore/mvc/razor-pages/index/sample/RazorPagesContacts/Pages/CreateCombined.cshtml
+++ /dev/null
@@ -1,35 +0,0 @@
-@page
-@using RazorPagesContacts.Data
-@using Microsoft.AspNetCore.Mvc.RazorPages
-@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-@inject AppDbContext Db
-
-@functions {
- [BindProperty]
- public Customer Customer { get; set; }
-
- public async Task OnPostAsync()
- {
- if (!ModelState.IsValid)
- {
- return Page();
- }
-
- Db.Customers.Add(Customer);
- await Db.SaveChangesAsync();
- return RedirectToPage("/Index");
- }
-}
-
-
-
-