Getting Started With Razor Pages In ASP.NET Core 2.0

ASP.NET Core 2.0 has introduced several new features and a new project template is among these new features. Microsoft has introduced some new project templates which help us to create new types of applications, except for MVC and Web API. Now, we can create Razor Page applications and SPA applications using Angular or React. Today, we will talk about more about Razor pages - what actually a Razor page is, how to create Razor page applications, and some of the fundamentals of Razor pages.

Razor Page is much like MVC and has most of the features of MVC, however, unlike MVC focusing on the controller, it focuses on UI implementation.  

Why Razor Page

The first question that comes to mind while reading about Razor page is "Why Razor Page instead of MVC?". To answer this question in one line, we can say "When focusing on UI or giving priority to UI rather than complex structure or data logic, we can go with Razor Page rather than MVC".

Actually, in an MVC project which has a Controller, View, Model, View-Model, Routing etc. grouped together to run your application, if you are adding or modifying one single functionality (like want to add one new property), then you have to make changes inside ViewModel, its corresponding Entity, its Mapping Data, as well as its View. 

But Razor Page is only for small applications where you have to mainly focus on View. If you make any changes, then you have to manipulate your Razor Page [.cshtml]. Server-side logic can be written on the Razor Page as well, using the @function directive. If you want to make a separate file to your logic, then you can create code-behind file which inherits PageModel.

Create Razor Page Application

To create a Razor Page application, you should have Visual Studio 2017 with version 15.3 or above with .NET Core SDK 2.0 installed on your system. You can download .NET Core SDK 2.0 from Here and update your Visual Studio using “Visual Studio Installer”.

For creating new Razor Page application, go to File >> New >>Project - as usual, we do for creating a new project.

From the "New Project" window, choose .NET Core from the left panel and “ASP.NET Core Web Application” from the center panel. then, provide the name of the application and location to save it and click OK.

ASP.NET Core 2.0

From the next window, you have to choose the template which is responsible to create a Razor page. Select “Web Application” as shown in teh below image. Change the authentication to “No Authentication” and click OK.

ASP.NET Core 2.0

After clicking OK, it will take a few seconds to configure your Razor Page Application. And finally, it will create your app as following.

ASP.NET Core 2.0
Above is the basic structure of the Razor Page. It is much like MVC application but here, you can see there are no Controller and Model folders. It has an important folder “Pages” which contains all the Razor pages and their corresponding code-behind files. The code-behind files or Model Pages are basically used for separation of concern. Other things, like Program.cs and Startup.cs, are most likely similar to MVC.

 Now, you can run the application and see the output as in the below screenshot shown.

ASP.NET Core 2.0

To add a new Razor page, just right-click Pages folder or any folder inside Pages and choose Add > Razor Page to add directly.

ASP.NET Core 2.0

It will open a new window, from where you can choose your Razor page's actual type. You might be using Razor with Entity Framework or you would like to write CRUD code automatically using Scaffold feature.

ASP.NET Core 2.0

Templating

The common Razor template is same as MVC like “_viewStart.cshtml”, “_layout.cshtml”, “about.cshtml” etc., but only folder structure has changed here with Razor Pages. In MVC, these have their predefined folders - for a common template, we use “Shared” folder inside the View folder and every functionality has its own View folder like Home, Employee etc.

@Page

Every Razor page has an @Page directive which indicates that this is not normal MVC Razor View but it is a Razor Page. 

  1. @page    
  2. @model AboutModel    
  3. @{    
  4.     ViewData["Title"] = "About";    
  5. }    
  6. <h2>@ViewData["Title"]</h2>    
  7. <h3>@Model.Message</h3>    
  8. <p>Use this area to provide additional information.</p>  

Code Behind or Model Page

To write server side logic, we can create a code-behind cshtml.cs file as the following code shown which contains all the server side login, like get the data from the server, post the data on server. Here, we use OnGet and OnPost handler to get and post the data. 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5. using Microsoft.AspNetCore.Mvc.RazorPages;  
  6.   
  7. namespace RazorPagesExample.Pages  
  8. {  
  9.     public class AboutModel : PageModel  
  10.     {  
  11.         public string Message { get; set; }  
  12.   
  13.         public void OnGet()  
  14.         {  
  15.             Message = "Your application description page.";  
  16.         }  
  17.     }  
  18. }  

Razor Page without Code Behind file.

Model Binding

We can bind the property directly with Razor Page using the [BindProperty] attribute. Property decorated with [BindProperty] attribute will automatically be available on Razor page.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel.DataAnnotations;  
  4. using System.Linq;  
  5. using System.Threading.Tasks;  
  6. using Microsoft.AspNetCore.Mvc;  
  7. using Microsoft.AspNetCore.Mvc.RazorPages;  
  8.   
  9. namespace RazorPagesExample.Pages.Employee  
  10. {  
  11.     public class IndexModel : PageModel  
  12.     {  
  13.         [BindProperty]  
  14.         public Employee employee { get; set; }  
  15.         public void OnGet()  
  16.         {  
  17.   
  18.         }  
  19.   
  20.         public void OnPost()  
  21.         {  
  22.             var data = employee;  
  23.         }  
  24.     }  
  25.   
  26.     public class Employee  
  27.     {  
  28.         public int ID { get; set; }  
  29.   
  30.         [Required]  
  31.         [StringLength(50, ErrorMessage = "Name lenght should be 1 to 50.")]  
  32.         [Display(Name = "Employee Name")]  
  33.         public string Name { get; set; }  
  34.   
  35.         [Required]  
  36.         [StringLength(255, ErrorMessage = "Address lenght should be 1 to 255.")]  
  37.         [Display(Name = "Address")]  
  38.         public string Address { get; set; }  
  39.     }  
  40. }  

On Razor page, just use the name of the property and bind the input control with this.

  1. @page  
  2. @model RazorPagesExample.Pages.Employee.IndexModel  
  3. @{  
  4.     ViewData["Title"] = "Employee Page";  
  5. }  
  6.   
  7. <h2>@ViewData["Title"]</h2>  
  8. <div class="row">  
  9.     <div class="col-md-6">  
  10.         <form method="post">  
  11.             <div class="form-group">  
  12.                 <label asp-for="employee.Name"></label>  
  13.                 <input asp-for="employee.Name" class="form-control" />  
  14.                 <span asp-validation-for="employee.Name" class="text-danger"></span>  
  15.             </div>  
  16.             <div class="form-group">  
  17.                 <label asp-for="employee.Address"></label>  
  18.                 <input asp-for="employee.Address" class="form-control" />  
  19.                 <span asp-validation-for="employee.Address" class="text-danger"></span>  
  20.             </div>  
  21.             <button type="submit" class="btn btn-default">Add Employee</button>  
  22.         </form>  
  23.     </div>  
  24. </div>  

Model Auto-Updating

Defined model with Razor page will update automatically on Code-Behind file. You don’t need to take care to bind your model with specific operation. Any changes inside the model data will get reflected in Model itself. 

You can see with above code if you click on “Add Employee” button and pass correct data to avoid the error then data will bind with model and reflect on OnPost handler as following. Here we are not passing model as parameter as we do in MVC.

ASP.NET Core 2.0

Tag Helpers

As we all know tag helper is basically a feature of Asp.Net MVC and has been included with Razor Page. Now you can bind your data with Razor Page directly using Tag Helpers. As the following code shows, we are using so many Tag Helpers here like “asp-for”, “asp-validation-for” etc; 

  1. <form method="post">  
  2.             <div class="form-group">  
  3.                 <label asp-for="employee.Name"></label>  
  4.                 <input asp-for="employee.Name" class="form-control" />  
  5.                 <span asp-validation-for="employee.Name" class="text-danger"></span>  
  6.             </div>  
  7.             <div class="form-group">  
  8.                 <label asp-for="employee.Address"></label>  
  9.                 <input asp-for="employee.Address" class="form-control" />  
  10.                 <span asp-validation-for="employee.Address" class="text-danger"></span>  
  11.             </div>  
  12.             <button type="submit" class="btn btn-default">Add Employee</button>  
  13.         </form>  

Handlers

We use handlers to perform server side operations like getting the data, posting the data. These handlers are something like Http Verb we used in MVC like Get(), Post() etc.

As a prefix, we use “On” with Http Verb in Razor Page which indicate as an event or handlers as OnGet() or OnGetAsync(), OnPost() or OnPostAsync() etc. 

Routing

As compared to MVC routing, Razor Page routing is very simple. We don’t have to write code manually for simple routing. All the pages inside Pages folder will call by file name after domain name.

  • http://localhost:51068/index
  • http://localhost:51068/about
  • http://localhost:51068/employee/index 

If you would like to pass parameters with a URL than you can add it with @page directive as following. Here you can see I am passing one id which is integer type.

  1. @page "{id:int}"  
  2. @model RazorPagesExample.Pages.Employee.IndexModel  
  3. @{  
  4.     ViewData["Title"] = "Employee Page";  
  5. }  

So, when you call the URL, you have to pass the ID which should be integer type as below URL.

http://localhost:51068/employee/index/1

Razor Page LocationRouting URL
/Pages/Index.cshtml/ OR /index
/Pages/About.cshtml/about
/Pages/Employee/Index.cshtml/employee OR /employee/index
/Pages/Employee/Index.cshtml with ID parameter /employee/index/1

Security

When we talk about security with Razor Page like CSRF attack, we don’t need the manual code to protect our application from the outer world as we do in MVC. We don’t need to add AntiRequestForgery Token or need to verify it. These tasks are done by Razor Page automatically internally. 

Conclusion

So today, we have learned what Razor pages are in ASP.NET Core 2.0, and what their fundamentals are.

I hope this post will help you. Please put your feedback in the comments which helps me to improve myself for the next post. If you have any doubts, please do not hesitate to ask and if you like this post, please share it with your friends.