ASP.NET Core 2.0 introduced the concept of Razor Pages and it was a useful addition to the existing features of .NET Core. Razor Pages are similar to the web forms model of ASP.NET web forms.
What is a Razor Page?
A Razor Page is more like a web form in the sense that it is focused on a single functionality, namely: view. A Razor Page has a view and a tightly coupled code logic that gets executed when any action is performed on the view of that page. A Razor Page allows the application to use cohesive code, which cannot be so effectively achieved using traditional Model-View-Controller (MVC) design patterns.
In this programming tutorial, we will be using ASP.NET Core 3.1 to create Razor web pages. The code examples used in this tutorial will work fine in any .NET application running version 3.1 or above, but if you are using a .NET version lower than version 3.1, you might need to perform some updates or the app examples will not work properly.
Let’s get started utilizing Razor Pages in ASP.NET using the default coding conventions.
Looking to learn how to program applications with C#? We have a list of the Best Online Courses to Learn C# to help you get started.
How to Add a Razor Page to an ASP.NET Application
As you may already know, when we add controllers in an MVC application, they are added to the Controllers folder and all the views reside in the Views folder. In the same way, Razor Pages are added conventionally to the Pages folder. This is the default file storage convention. Developers can also add Razor Pages in another folder, but they would not work properly unless the same convention is followed.
To create a Razor Page in a .NET Core app, open up Visual Studio. You need to first create a folder named Pages and then right-click the folder, select the Add option, and select Razor Page to create a new Razor Page.
Give the newly created Razor page a name. For the examples in this tutorial, we are naming the page Index.cshtml. After you click on the Add button, Visual Studio will automatically create two files: the first one is an Index.cshtml file and the other one is an Index.cstml.cs file, which is just a behind-the-scenes file of our Index HTML View.
Inside the PageModel class, we set the public property ‘Message’ in the onGet handler, as seen here:
public class IndexModel : PageModel { public string Message { get; set; } public void OnGet() { this.Message = "Hello there!"; } }
Next, inside the Razor HTML page, we displayed the ‘Message’ property by accessing it from the Razor PageModel class:
@page @model RazorPageExample.Pages.IndexModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"/> <title>Index</title> </head> <body> <h3>@Model.Message</h3> </body> </html>
Read: Top Unit Testing Tools for Developers
Routing Razor Pages
Next, let’s see how routing is configured when working with Razor pages. Conventionally, Razor Pages are directly mapped to physical files. This means if you have a file named Index.cshtml, then it can be accessed by the following route:
http://<your_domainname>/Index
But note that, to utilize Razor Pages in a .NET app, you need to first enable the support for Razor Pages inside the startup.cs class file.
First, configure the service in the ConfigureServices method to use Razor Pages in an ASP.NET web app:
Next, configure the routing endpoints accordingly:
Model Binding in an ASP.NET Razor Page
As in Model-View-Controller (MVC) architecture, the parameter of an action method is bound to the incoming request by matching values in the query string, URL, or body of the request. Razor Pages, on the other hand, bound the incoming request with the properties of PageModel.
Note that developers have to explicitly bind the properties using the [BindProperty] attribute. The following example shows the two properties – one of which is bound to the request and that is decorated with [BindProperty] and the other (the one without the attribute), which is not:
using Microsoft.AspNetCore.Mvc.RazorPages; public class IndexModel : PageModel { [BindProperty] public string CompanyName { get;set; } public string Address { get; set; }; }
Razor Page Handlers
One advantage of using Razor Pages is that they bring cohesion in code maintainability, as opposed to the MVC architecture, which does not. A Razor Page responds to requests by using page handlers. You can think of page handlers as being similar to action methods in MVC. Razor Pages execute a single handler based on the handler name and request when receiving a request from a user. They use the following convention to match a handler request:
On{Verb}[Async] Where {Verb} is an HTTP method, and [Async] is optional
In any typical HTML form, the OnGet handler initiates an empty form while the OnPost handler handles the post request generated by the client. To understand it better, consider the following code snippet, in which we are fetching the username from a service in an OnGet() method and updating it in the OnPostAsync() method:
[BindProperty] public InputModel Input { get; set; } public void OnGet() { Input.UserName = mailService.GetUserName(); } public async Task OnPostAsync() { if (!ModelState.IsValid) { // return page } mailService.UpdateUserName(User, Input.UserName); return RedirectToPage("/Index"); }
Final Thoughts on Razor Pages in ASP.NET
Razor Pages are built on top of ASP.NET primitives, which serve the same functionality as the MVC architecture, but with a page-based approach. In the modern world, there are many apps which require code to be cohesive in order to operate effectively, and in such scenarios programmers can use PageModel, which is a page-based approach used in Razor Pages, to meet the demands of such apps.
Read more ASP.NET programming tutorials and software development tips.