ASP.NET Core 8 Website - Named Razor Handler with fetch()

PART 8: Using a Named Razor Handler with fetch()

PART 7 calculated the server time during the normal Home-page request. This part creates a separate named handler and uses JavaScript to request its value without reloading the complete page.

1. The new request flow

RequestPurposeHandler
GET /Load the Home pageOnGet()
GET /?handler=TimeRetrieve only the server timeOnGetTime()

2. Update Pages/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace basicdotnet.Pages;

public class IndexModel : PageModel
{
    public void OnGet()
    {
    }

    public IActionResult OnGetTime()
    {
        string serverTime = DateTime.Now.ToString("HH:mm:ss");
        return Content(serverTime);
    }
}

3. Understand the named handler

Razor Pages uses a naming convention for handler methods:

On + HTTP verb + optional handler name
MethodHTTP verbHandler name
OnGet()GETNone
OnGetTime()GETTime
OnPostSave()POSTSave

The query value below selects the Time handler:

?handler=Time

4. Understand IActionResult

public IActionResult OnGetTime()

IActionResult allows the handler to return different HTTP results. Here, Content() returns a short text response:

return Content(serverTime);

A direct request to /?handler=Time should display only a value such as:

19:08:42

5. Update Pages/Index.cshtml

@page
@model IndexModel

@{
    ViewData["Title"] = "Home";
}

<main class="page-content home-content">
    <h1>Welcome to basicdotnet</h1>

    <p>
        A simple ASP.NET Core web app built
        with Razor Pages.
    </p>

    <p>
        It's <span id="server-time">loading...</span>
        on the server.
    </p>
</main>

<script>
    const serverTimeElement =
        document.getElementById("server-time");

    fetch("/?handler=Time")
        .then(response => {
            if (!response.ok) {
                throw new Error("Unable to retrieve server time.");
            }

            return response.text();
        })
        .then(serverTime => {
            serverTimeElement.textContent = serverTime;
        })
        .catch(() => {
            serverTimeElement.textContent = "unknown";
        });
</script>

6. Understand the placeholder

<span id="server-time">loading...</span>

The page initially displays loading.... JavaScript later replaces that text with the handler response.

7. Understand fetch()

fetch("/?handler=Time")

This sends a separate GET request to the Home Razor Page and selects its named Time handler.

The first callback checks whether the HTTP request succeeded and converts the response into text:

.then(response => {
    if (!response.ok) {
        throw new Error("Unable to retrieve server time.");
    }

    return response.text();
})

The next callback inserts the returned time safely into the page:

.then(serverTime => {
    serverTimeElement.textContent = serverTime;
})

If the request fails, the page displays unknown:

.catch(() => {
    serverTimeElement.textContent = "unknown";
});

8. Keep the other files unchanged

No changes are required to:

  • Program.cs
  • Pages/Shared/_Layout.cshtml
  • Pages/_ViewImports.cshtml
  • Pages/_ViewStart.cshtml
  • Pages/Privacy.cshtml and its Page Model
  • Pages/NotFound.cshtml and its Page Model
  • wwwroot/css/site.css

9. Build and run

dotnet build
dotnet run

10. Test the handler directly

Open the exact address printed by dotnet run, followed by:

/?handler=Time

For example:

http://localhost:5273/?handler=Time

The browser should show only the current server time.

11. Test the Home page

Open /. The browser performs two requests:

SequenceRequestResponse
1GET /Complete Home HTML
2GET /?handler=TimePlain server-time text

The Home page first shows loading... and then replaces it with the returned time.

12. Inspect the request in Developer Tools

  1. Press F12 in the browser.
  2. Open the Network tab.
  3. Refresh the Home page.
  4. Select the request containing handler=Time.
  5. Inspect its status and response.

The request should return status 200 OK and a short text response.

Server rendering versus client-side retrieval

PART 7PART 8
Time calculated during page renderingTime requested after page rendering
Displayed through @Model.ServerTimeDisplayed through JavaScript
One requestTwo requests
Refresh updates the valueHandler can be called independently

What has been achieved?

  • A named Razor Page handler was created.
  • The handler returns a small plain-text response.
  • JavaScript retrieves server data asynchronously.
  • The Home page updates without a full second page load.
  • The project now reproduces the server-time behaviour of the target application.

The application now has the correct Razor Pages behaviour, but its navigation and styling are still custom. The next part will introduce Bootstrap and ASP.NET Core Tag Helpers to move the interface closer to the default Razor Pages template.

Next: PART 9 adds Bootstrap styling and replaces hard-coded navigation URLs with the asp-page Tag Helper.