Practical .NET

Extending Razor Pages

If you move beyond the basics of working with Razor Pages, there are at least two things you should know to support creating Pages that do more than one thing and integrate with existing code.

In an earlier column, I advocated for Razor Pages as a better model for Web Development than the Model-View-Controller pattern. I demonstrated why I thought that way in a followup column.

But that second column just covered the basics of building Razor Pages. Here's two more things that you'll need to do with Razor Pages.

Multi-Purpose Forms
First, it's not unusual to have a View that needs more than a single processing method -- a page that supports both updating and deleting customers, for example.

The easiest way to implement that in a Razor Page is to put what you consider the "primary" function of the page behind the submit button. On a page that allows users to both update and delete a customer, the "primary" function would probably be the update function. Clicking the submit button will automatically trigger the OnPost method in your Razor Page's code file, so you should put the update code in the OnPost method.

You can implement any "secondary" activities -- deleting the customer, in this scenario -- through an anchor tag (you're free, of course, to style that anchor tag to look like a button, if you want). In the View component of your Razor Page, your anchor tag must include an asp-page-handler attribute, and you set that attribute to some string value of your choice.

In this example, since I'm supporting deleting customers, it made sense to me to set the handler's value to "Delete":

<a asp-page="/Customers/Update" asp-page-handler="Delete">Delete</a>

Your next step is to tie an OnGet or OnPost method to the value you set in the handler attribute and put the "delete customer" code in that method. To tie an OnGet method to my anchor tag with its handler set to "Delete," I'd create a method like this:

public void OnGetDelete()
{

Following this pattern, the code file for your Razor Page will typically have an OnGet method to support the initial display of the page, an OnPost method to support the "primary" update functionality and, potentially, multiple OnGet<handler> methods to support "secondary" functionality.

If you're uncomfortable with using OnGet methods to do updates (which does violate RESTful standards), you can also add handlers to your submit buttons using Tag Helpers. This example will, when clicked, invoke my Page's OnPostDelete method:

<input type="submit" value="Delete Customer" asp-route-handler="delete" />

Using Tag Helpers, you can also add a handler to your form's postback method. This might make sense if you're going to dynamically set the handler name when a View is requested. This example uses a property on the Model property to set the method being called:

<form asp-page-handler="@Model.HandlerName" method="post">

If, within a Controller's Action method, you're using the RedirectToPageResult method to send the user to a Page, you can pass your handler value as the second parameter to the method. That would also let you have multiple OnGet<handler> methods to handle the initial display of your page.

Integrating with ASP.NET MVC
As fond as I am of Razor Pages, I don't want to suggest that there isn't a role for the Controllers-and-Views approach (it's the obvious option when you have a method that needs to choose between different views). In addition, if you want to add additional functionality to an existing MVC application with Razor Pages, that will be easier if your new Pages can work with existing Controllers. In either scenario, you're going to need to integrate Razor Pages with Controllers.

Fortunately, that's easy to do. By default, your Razor Page methods return void. However, you can change them to return IActionResult, the interface implemented by the objects typically returned from a Controller's Action methods. This is a perfectly acceptable OnPost method, for example:

public IActionResult OnPost()
{

This allows you, from within your Razor Page methods, to integrate your Razor Pages with Controllers and Action methods. The PageModel class that your RazorPage inherits from includes a RedirectToRoute method, for example, that accepts Controller and Action method names. To send the user to the DisplayList method in the Customer controller at the end of a method, you could use code like this:

return RedirectToRoute("DisplayList", "Customer");

In these three columns I've tried to make a case for Razor Pages as a better model for creating Web applications, to show how to create Razor Pages and (in this column) to provide tools and advice for real-world application. Now you should be trying Pages out and seeing if you agree.

For convenience, the first two columns are:

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 http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Compare New GitHub Copilot Free Plan for Visual Studio/VS Code to Paid Plans

    The free plan restricts the number of completions, chat requests and access to AI models, being suitable for occasional users and small projects.

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

Subscribe on YouTube