ASP.
Net Core –Creating a web site
with Razor Pages
Kamal Beydoun
Lebanese University – Faculty of Sciences I
[email protected] An introduction to Razor Pages
• The Razor Pages programming model was introduced in ASP.NET Core
2.0 as a way to build server-side rendered “page-based” web sites.
• It builds on top of the ASP.NET Core infrastructure to provide a
streamlined experience, using conventions where possible to reduce the
amount of boilerplate code and configuration required.
2
Exploring a typical Razor Page
• This page is taken from a to-do list application and is used to display all
the to-do items for a given category.
The Razor View has access to the CategoryModel instance,
so it can access the Items property that is set by the handler.
It uses these items to build the HTML that is ultimately sent
to the user.
3
The MVC design pattern
Fundamentally MVC pattern aims to separate the management and
manipulation of data from its visual representation.
4
The MVC design pattern
In general, three components make up the MVC design pattern:
Model—The data that needs to be displayed, the globale state of the
application.
Accessed via the ToDoService in Listing 4.1.
View—The template that displays the data provided by the model.
Controller—Updates the model and selects the appropriate view.
This role is taken by the page handler in Razor Pages. This is the OnGet method in listing
4.1.
5
MVC : Order of events
6
Applying the MVC design pattern to Razor
Pages
ASP.NET Core also includes a framework called ASP.NET Core MVC.
This framework very closely mirrors the MVC design pattern, using
controllers and action methods in place of Razor Pages and page handlers.
Razor Pages builds directly on top of the underlying ASP.NET Core MVC
framework, using the MVC framework “under the hood” for their behavior.
You can avoid Razor Pages entirely, and work with the MVC framework
directly in ASP.NET Core.
This was the only option in early versions of ASP.NET Core
7
Applying the MVC design pattern to Razor
Pages
8
DIRECTING A REQUEST TO A RAZOR PAGE
AND BUILDING A BINDING MODEL
A binding model is
one or more objects
that act as a
“container” for the
data provided in a
request that’s
required by a page
handler.
9
EXECUTING A HANDLER USING THE
APPLICATION MODEL
The role of the page handler as the controller in the MVC pattern is to
coordinate the generation of a response to the request it’s handling.
It should perform only a limited number of actions :
Validate that the data contained in the binding model provided is valid for the
request.
Invoke the appropriate actions on the application model using services.
Select an appropriate response to generate based on the response from the
application model.
10
EXECUTING A HANDLER USING THE
APPLICATION MODEL
11
BUILDING HTML USING THE VIEW
MODEL
A view model is all the data required by the view to render a UI.
It’s typically some transformation of the data contained in the application
model, plus extra information required to render the page, for example the
page’s title.
12
BUILDING HTML USING THE VIEW
MODEL
13
A COMPLETE RAZOR PAGE REQUEST
14
Benefits
The key benefit throughout this process is the separation of concerns:
The view is responsible only for taking some data and generating HTML.
The application model is responsible only for executing the required
business logic.
The page handler (controller) is responsible only for validating the
incoming request and selecting the appropriate view to display, based on
the output of the application model.
15
Adding Razor Pages to your application
16
Adding Razor Pages to your application
Add the necessary Razor Page services (in bold) in your Startup.cs file’s
ConfigureServices method
17
Adding Razor Pages to your application
Replace the existing basic endpoint configured in the EndpointMiddleware
at the end of your middleware pipeline with the MapRazorPages( ) extension
method.
18
Adding Razor Pages to your application
• Right-click your project in Solution Explorer and choose Add > New
Folder to add a new folder to the root of your project. Name the new
folder Pages.
19
Adding Razor Pages to your application
20
Razor Pages vs MVC in ASP.NET Core
• We focus on Razor Pages, as that has become the recommended approach
for building server-side rendered applications with ASP.NET Core.
• Razor Pages uses the ASP.NET Core MVC framework behind the scenes
• If you’re creating a Web API for working with mobile or client-side apps
then you will almost certainly be using the MVC framework directly
21
MVC controllers in ASP.NET Core
Instead of a PageModel and page handler, MVC uses a concept of
controllers and action methods.
An action (or action method) is a method that runs in response to a
request. An MVC controller is a class that contains a number of logically
grouped action methods.
MVC controllers use explicit view models to pass data to a Razor view,
rather than exposing the data as properties on itself (as Razor Pages do
with Page Models).
22
23
24
The benefits of Razor Pages
In MVC, a single controller can have multiple action methods. Each action handles
a different request and generates a different response.
Unfortunately, you can often find that your controllers become very large and bloated, with
many dependencies
Another pitfall of the MVC controllers are the way they’re typically organized in
your project. Most action methods in a controller will need an associated Razor
view, and a view model for passing data to the view.
The MVC approach traditionally groups classes by type (controller, view, view model), while
the Razor Page approach groups by function—everything related to a specific page is co-
located.
25
Folder structure
You can think of each Razor Page as a
mini controller focused on a single page.
Page handlers are functionally
equivalent to MVC controller action
methods.
26
Razor Pages and page handlers
For Razor Pages, the entry point is a page handler that resides in a Razor Page’s
PageModel.
A page handler is a method that runs in response to a request.
By default, the path of a Razor Page on disk controls the URL path that the Razor
Page responds to.
For example, a request to the URL /products/list corresponds to the Razor Page at
the path Pages/Products/List.cshtml.
Razor Pages can contain any number of page handlers, but only one runs in
response to a given request.
27
Page handlers
The responsibility of a page handler is generally threefold:
Confirm the incoming request is valid.
Invoke the appropriate business logic corresponding to the incoming
request.
Choose the appropriate kind of response to return.
28
Page handlers
Page Handlers typically return one of 3 things:
• A PageResult object. This causes the associated Razor view to generate an
HTML response.
• Nothing (the handler returns void or Task). This is the same as the
previous case, causing the Razor view to generate an HTML response.
• A RedirectToPageResult. This indicates the user should be redirected to a
different page in your application.
29
Accepting parameters to page handlers
Some requests made to page handlers will require additional values with details about
the request.
The request may contain additional values from a variety of different sources:
part of the URL,
the query string,
headers,
or in the body of the request itself.
The middleware will extract values from each of these sources and convert them
into .NET types (Binding).
30
Binding
ASP.NET Core can bind two different targets in Razor Pages:
Method arguments. If a page handler has method arguments,
the values from the request are used to create the required
parameters.
Properties marked with a [BindProperty] attribute. Any
properties marked with the attribute will be bound.
By default, this attribute does nothing for GET requests.
31
If you’re returning more than one type
of result from a page handler, you’ll
need to ensure your method returns an
IActionResult.
32
Returning responses with ActionResults
ASP.NET Core has many different types of IActionResult:
• PageResult—Generates an HTML view for an associated page in Razor Pages.
• ViewResult—Generates an HTML view for a given Razor view when using MVC controllers.
• RedirectToPageResult—Sends a 302 HTTP redirect response to automatically send a user to another page.
• RedirectResult—Sends a 302 HTTP redirect response to automatically send a user to a specified URL (doesn’t
have to be a Razor Page).
• FileResult—Returns a file as the response.
• ContentResult—Returns a provided string as the response.
• StatusCodeResult—Sends a raw HTTP status code as the response, optionally with associated response body
content.
• NotFoundResult—Sends a raw 404 HTTP status code as the response.
33
PAGERESULT AND
REDIRECTTOPAGERESULT
34
Summary
The MVC design pattern allows for a separation of concerns between the business logic of your application, the
data that’s passed around, and the display of data in a response.
Razor Pages are built on the ASP.NET Core MVC framework and use many of the same primitives. They use
conventions and a different project layout to optimize for page-based scenarios.
MVC controllers contain multiple action methods, typically grouped around a high-level entity. Razor Pages
groups all the page handlers for a single page in one place, grouping around a page/feature instead of an entity.
Each Razor Page is equivalent to a mini controller focused on a single page, and each Razor Page handler
corresponds to a separate action method.
Razor Pages should inherit from the PageModel base class.
A single Razor Page handler is selected based on the incoming request’s URL, the HTTP verb, and the request’s
query string, in a process called routing.
35
Summary
• Page handlers should generally delegate to services to handle the business logic required by a request,
instead of performing the changes themselves. This ensures a clean separation of concerns that aids
testing and improves application structure.
• Page handlers can have parameters whose values are taken from properties of the incoming request in a
process called model binding. Properties decorated with [BindProperty] can also be bound to the request.
• By default, properties decorated with [BindProperty] are not bound for GET requests. To enable binding,
use [BindProperty(SupportsGet = true)].
• Page Handlers can return a PageResult or void to generate an HTML response.
• You can send users to a new Razor Page using a RedirectToPageResult.
• The PageModel base class exposes many helper methods for creating an ActionResult.
36