Exercise - Customize the project
Your team has split up the work for the pizza inventory management app. Your teammates have created the ASP.NET Core web app for you, and they've already built a service to read and write pizza data to a database. You've been assigned to work on the Pizza List page, which will display a list of pizzas and allow you to add new pizzas to the database. We'll start by taking a tour of the project to understand how it's organized.
Note
This module uses the .NET CLI (Command Line Interface) and Visual Studio Code for local development. After completing this module, you can apply the concepts using Visual Studio (Windows) or continued development using Visual Studio Code (Windows, Linux, and macOS).
Obtain the project files
If you're using GitHub Codespaces, just open the repository in the browser, select Code, and then create a new codespace on the main
branch.
If you aren't using GitHub Codespaces, obtain the project files and open them in Visual Studio Code with the following steps:
Open a command shell and clone the project from GitHub using the command line:
git clone https://github.com/MicrosoftDocs/mslearn-create-razor-pages-aspnet-core
Navigate to the
mslearn-create-razor-pages-aspnet-core
directory and open the project in Visual Studio Code:cd mslearn-create-razor-pages-aspnet-core code .
Tip
If you've got a compatible container runtime installed, you can use the Dev Containers extension to open the repository in a container with the tools preinstalled.
Review your teammates' work
Let's take a moment to get familiar with the existing code in the ContosoPizza folder. The project is an ASP.NET Core web app created using the dotnet new webapp
command. The changes your teammates made are described below.
Tip
Don't spend too much time reviewing these changes. Your teammates have already done the work to create the database and the service to read and write pizzas to the database, but they didn't make any UI changes. You'll be building a UI that consumes their service in the next unit.
- A Models folder was added to the project.
- The model folder contains a
Pizza
class that represents a pizza.
- The model folder contains a
- A Data folder was added to the project.
- The data folder contains a
PizzaContext
class that represents the database context. It inherits from theDbContext
class in Entity Framework Core. Entity Framework Core is an object-relational mapper (ORM) that makes it easier to work with databases.
- The data folder contains a
- A Services folder was added to the project.
- The services folder contains a
PizzaService
class that exposes methods to list and add pizzas. - The
PizzaService
class uses thePizzaContext
class to read and write pizzas to the database. - The class is registered for dependency injection in Program.cs (line 10).
- The services folder contains a
Entity Framework Core generated a few things, too:
- A Migrations folder was generated.
- The migrations folder contains code to create the database schema.
- The SQLite database file ContosoPizza.db was generated.
- If you have the SQLite extension installed (or you're using GitHub Codespaces), you can view the database by right-clicking the file and selecting Open Database. The database schema is shown in the SQLite Explorer tab of the Explorer pane.
Review the Razor Pages project structure
Everything else in the project is unchanged from when the project was created. The following table describes the project structure that was generated by the dotnet new webapp
command.
Name | Description |
---|---|
Pages/ | Contains Razor Pages and supporting files. Each Razor page has a .cshtml file and a .cshtml.cs PageModel class file. |
wwwroot/ | Contains static asset files like HTML, JavaScript, and CSS. |
ContosoPizza.csproj | Contains project configuration metadata, such as dependencies. |
Program.cs | Serves as the app's entry point and configures app behavior, like routing. |
Other noteworthy observations:
Razor page files and their paired
PageModel
class fileRazor pages are stored in the Pages directory. As noted above, each Razor page has a .cshtml file and a .cshtml.cs
PageModel
class file. ThePageModel
class allows separation of a Razor page's logic and presentation, defines page handlers for requests, and encapsulates data properties and logic scoped to its Razor page.The Pages directory structure and routing requests
Razor Pages uses the Pages directory structure as the convention for routing requests. The following table shows how URLs map to filenames:
URL Maps to Razor page www.domain.com
Pages/Index.cshtml www.domain.com/Index
Pages/Index.cshtml www.domain.com/Privacy
Pages/Privacy.cshtml www.domain.com/Error
Pages/Error.cshtml Subfolders in the Pages directory are used to organize Razor pages. For example, if there were a Pages/Products directory, the URLs would reflect that structure:
URL Maps to Razor page www.domain.com/Products
Pages/Products/Index.cshtml www.domain.com/Products/Index
Pages/Products/Index.cshtml www.domain.com/Products/Create
Pages/Products/Create.cshtml Layout and other shared files
There are several files that are shared across multiple pages. These files determine common layout elements and page imports. The following table describes the purpose of each file.
File Description _ViewImports.cshtml Imports namespaces and classes that are used across multiple pages. _ViewStart.cshtml Specifies the default layout for all Razor pages. Pages/Shared/_Layout.cshtml This is the layout specified by the _ViewStart.cshtml
file. Implements common layout elements across multiple pages.Pages/Shared/_ValidationScriptsPartial.cshtml Provides validation functionality to all pages.
Run the project for the first time
Let's run the project so we can see it in action.
Right-click on the ContosoPizza folder in the Explorer and select Open in Integrated Terminal. This opens a terminal window in the context of the project folder.
In the terminal window, enter the following command:
dotnet watch
This command:
- Builds the project.
- Starts the app.
- Watches for file changes and restarts the app when it detects a change.
The IDE prompts you to open the app in a browser. Select Open in Browser.
Tip
You can also open the app by finding the URL in the terminal window. Hold Ctrl and click the URL to open it in a browser.
Compare the rendered home page to Pages/Index.cshtml in the IDE:
- Observe the combination of HTML, Razor Syntax, and C# code in the file.
- Razor Syntax is denoted by
@
characters. - C# code is enclosed in
@{ }
blocks. Take note of the directives at the top of the file: - The
@page
directive specifies that this file is a Razor page. - The
@model
directive specifies the model type for the page (in this case,IndexModel
, which is defined in Pages/Index.cshtml.cs).
- Razor Syntax is denoted by
- Review the C# code block.
- The code sets the value of the
Title
item within theViewData
dictionary to "Home page". - The
ViewData
dictionary is used to pass data between the Razor page and theIndexModel
class. - At runtime, the
Title
value is used to set the page's<title>
element.
- The code sets the value of the
- Observe the combination of HTML, Razor Syntax, and C# code in the file.
Leave the app running in the terminal window. We'll use it in the upcoming units. Leave the browser tab with the running Contoso Pizza app, too. You'll make changes to the app and the browser will automatically refresh to display the changes.
Customize the landing page
Let's make a few changes to the landing page to make it more relevant to the pizza app.
In Pages/Index.cshtml, replace the code in the C# code block with the following code:
ViewData["Title"] = "The Home for Pizza Lovers"; TimeSpan timeInBusiness = DateTime.Now - new DateTime(2018, 8, 14);
The preceding code:
- Sets the value of the
Title
item within theViewData
dictionary to "The Home for Pizza Lovers". - Calculates the amount of time that has passed since the business opened.
- Sets the value of the
Modify the HTML as follows:
Replace the
<h1>
element with the following code:<h1 class="display-4">Welcome to Contoso Pizza</h1>
Replace the
<p>
element with the following code:<p class="lead">The best pizza in town for @Convert.ToInt32(timeInBusiness.TotalDays) days!</p>
The preceding code:
- Changes the heading to "Welcome to Contoso Pizza".
- Displays the number of days that have passed since the business opened.
- The
@
character is used to switch from HTML to Razor Syntax. - The
Convert.ToInt32
method is used to convert theTotalDays
property of thetimeInBusiness
variable to an integer. - The
Convert
class is part of theSystem
namespace, which is imported automatically by the<ImplicitUsings>
element in the ContosoPizza.csproj file.
- The
Save the file. The browser tab with the app automatically refreshes to display the changes. If you're using GitHub Codespaces, the file saves automatically, but you'll need to refresh the browser tab manually.
Important
Keep a close eye on the terminal window with dotnet watch
every time you save your file. Sometimes your code might contain what it calls a rude edit. This means that the code you changed can't be recompiled without restarting the application. If prompted to restart the app, press y
(yes) or a
(always). You can always stop the application by pressing Ctrl+C twice in the terminal window, and then restart it by running dotnet watch
again.
You've made your first changes to a Razor page! In the next unit, you'll add a new page to the app to display a list of pizzas.