Practical .NET

Getting Started with Razor Pages: A Better Model for Web Development?

As fond as he is of using Controllers and Views, Peter isn't sure that Razor Pages aren't a better model for Web development. But the first step, adding Razor Pages to your project, isn't as easy as it should be. And, after that, you'll want to integrate them with your existing MVC application.

I like ASP.NET Core's Razor Pages because, in my mind, I think they do a better job of implementing the Single Responsibility Principle than the "standard" MVC model of Controller+View. While a Controller typically manages multiple Views and functionalities, the Razor Pages model encourages more focused models: A Razor Page is dedicated to supporting the functionality of a View. This means that Razor Pages are more focused and, as a result, easier to understand, maintain, document, test and assign to different teams.

But adopting Razor Pages isn't free: I have to give up Action methods that finish by selecting between different Views. However, to be realistic, the number of Action methods where I take advantage of choosing Views is very small. In fact, where I do want to use a different View, I'm more likely to use the RedirectToAction method than use multiple Views ... and that option is also available in Razor Pages.

The Razor Pages Model
One way to think of the Razor Page's model as collapsing into the Controller the Data Transfer Object (DTO or "model" object) that, in the "standard" MVC model is created by the Controller and passed to the View. This removes another option I have with the "standard" model: The ability to use one DTO with several different Views.

Again, this is an option that I don't often use. In fact, many developers are opposed to sharing DTOs among Views, feeling that each "model" object should be tailored to a single View (even (to the point of using different DTOs for a View's HttpGet and HttpPost methods).

This collapse does reduce the number of files in Solution Explorer by 33 percent. In fact, the number of files in Solution Explorer decreases by 66 percent because, like the old "code behind" model for Windows Forms, the file with the Razor Page's code nests underneath the View file in Solution Explorer. This means that all the components of a Razor Page are in one place rather than being spread among the Controllers, Models and Views folders.

Unlike that old "code-behind" model, though, a Razor Page's code model is divorced from its View and, like a Controller, can be tested completely independently of its View.

Adding Razor Pages: Annoyances
In my experience, however, adding your first Razor Page to a project isn't as easy as it should be: Razor Pages must be kept in a Pages folder in your site, and the initial mechanism for adding Pages won't create that folder for you. You'll need to right-click on your project in Solution Explorer, select Add Folder and, when the Add Folder dialog is displayed, add a Folder called Pages.

Once that Pages folder is created, you can right-click on it and select Add | New Item to display the Add New Item dialog. On the left side of that dialog, you'll need to ensure that the ASP.NET Core option is selected to get the list of ASP.NET Core item templates. From that list, select Razor Page, give your page a name and click the Add button.

You'll now find that you have two files: a cshtml file (your View) and a cshtml.cs file (your Controller/DTO file). The name of the class in that cshtml.cs file will be name of your Razor Page with "Model" tacked on at the end (your class must also inherit from the PageModel class).

For a Razor Page called Customer, then, the code file will look like this:

namespace CustomerManagement.Pages
  public class CustomerModel : PageModel

You'll find that your View file begins like this:

@model CustomerModel

The page directive is required. The model directive should refer to the class but, for the first Razor Page you add, there won't be a namespace directive and the compiler won't be able to find the related class. So, you'll need to modify your View to reference the code file's namespace:

@using CustomerManagement.Pages
@model CustomerModel

More changes are required if, for example, you want to use a layout View with your Page.

Again, in my experience, these annoyances go away as you add your subsequent Razor Pages. Once you've added that first Razor Page to a project's Pages folder, the next time you right-click on the Pages folder, you'll find a new Add Page choice in the pop-up menu. That choice brings up an Add Scaffolding dialog, which lists nothing but Razor Page templates.

With that dialog, after you select the template you want and click the Add button, you'll get an Add Razor Page dialog. This dialog gives you several checkoff options for creating your Page, including whether you want a separate code file, use a Layout page or create your Razor Page as partial page. The View file will then be added with all the directives you need for it to, you know, work.

Integrating Razor Pages
With a Razor Page in place, I can integrate that Page with an Action method by using the RedirectToPage method in a Controller. This code in an Action would send the user to a CustomerManagement Page in my project's Pages folder:

return RedirectToPage("/CustomerManagement");

Similar code in the Page's code file allows me to redirect users to other Pages in the project.

I can also integrate Pages both with other Pages and Action methods. Methods in Razor Pages follow the Web API standard of tying methods to HTTP verbs: Method names in Pages have names like OnGet/OnGetAsync, OnPost/OnPostAsync and so on. So, a typical method in a Page's code file to redirect to the user to another page would look like this:

public IActionResult OnPost()
   return this.RedirectToPage("/FirstPage");

If, on the other hand, I wanted to send the user to an Action method in a Controller, I would use this code in my Razor Page method:

public IActionResult OnPost()
   return this.RedirectToAction("Index", "Home");

Of course, all this leaves open how you actually use a Razor Page. I'll return to that later this month.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at

comments powered by Disqus


  • What's New in Visual Studio 2019 v16.5 Preview 2

    The second preview of Visual Studio 2019 v16.5 has arrived with improvements across the flagship IDE, including the core experience and different development areas such as C++, Python, web, mobile and so on.

  • C# Shows Strong in Tech Skills Reports

    Microsoft's C# programming language continues to show strong in tech industry skills reports, with the most recent examples coming from a skills testing company and a training company.

  • Color Shards

    Sharing Data and Splitting Components in Blazor

    ASP.NET Core Version 3.1 has at least two major changes that you'll want to take advantage of. Well, Peter thinks you will. Depending on your background, your response to one of them may be a resounding “meh.”

  • Architecture Small Graphic

    Microsoft Ships Preview SDK, Guidance for New Dual-Screen Mobile Era

    Microsoft announced a new SDK and developer guidance for dealing with the new dual-screen mobile era, ushered in by the advent of ultra-portable devices such as the Surface Duo.

  • How to Create a Machine Learning Decision Tree Classifier Using C#

    After earlier explaining how to compute disorder and split data in his exploration of machine learning decision tree classifiers, resident data scientist Dr. James McCaffrey of Microsoft Research now shows how to use the splitting and disorder code to create a working decision tree classifier.

.NET Insight

Sign up for our newsletter.

Terms and Privacy Policy consent

I agree to this site's Privacy Policy.

Upcoming Events