ASP.NET Core 8 Website - Razor Pages
PART 5: Converting the Application to Razor Pages
This part moves Home and Privacy out of C# strings and into .cshtml files. The shared layout will be introduced in PART 6.
1. Create the Pages directory
mkdir Pages
2. Replace Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.MapFallback(() =>
{
string html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Not Found - basicdotnet</title>
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<header class="site-header">
<nav class="navigation">
<a class="site-name" href="/">basicdotnet</a>
<a class="nav-link" href="/">Home</a>
<a class="nav-link" href="/privacy">Privacy</a>
</nav>
</header>
<main class="page-content">
<h1 class="error-code">404 - Page Not Found</h1>
<p>The requested page could not be found.</p>
<p><a href="/">Return to the Home page</a></p>
</main>
</body>
</html>
""";
return Results.Content(html, "text/html",
statusCode: StatusCodes.Status404NotFound);
});
app.Run();
AddRazorPages() registers the required services. MapRazorPages() discovers pages and maps their routes.
3. Create Pages/Index.cshtml
@page
@{
ViewData["Title"] = "Home";
string serverTime = DateTime.Now.ToString("HH:mm:ss");
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewData["Title"] - basicdotnet</title>
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<header class="site-header">
<nav class="navigation">
<a class="site-name" href="/">basicdotnet</a>
<a class="nav-link" href="/">Home</a>
<a class="nav-link" href="/privacy">Privacy</a>
</nav>
</header>
<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 @serverTime on the server.</p>
</main>
</body>
</html>
4. Create Pages/Privacy.cshtml
@page
@{
ViewData["Title"] = "Privacy Policy";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewData["Title"] - basicdotnet</title>
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<header class="site-header">
<nav class="navigation">
<a class="site-name" href="/">basicdotnet</a>
<a class="nav-link" href="/">Home</a>
<a class="nav-link" href="/privacy">Privacy</a>
</nav>
</header>
<main class="page-content">
<h1>@ViewData["Title"]</h1>
<p>basicdotnet is a demonstration application.</p>
<p>This website does not collect or store personal information.</p>
</main>
</body>
</html>
5. Check the structure
basicdotnet/
├── Pages/
│ ├── Index.cshtml
│ └── Privacy.cshtml
├── wwwroot/
│ └── css/site.css
├── basicdotnet.csproj
└── Program.cs
6. Build, run and test
dotnet build
dotnet run
| URL | Source |
|---|---|
/ | Pages/Index.cshtml |
/privacy | Pages/Privacy.cshtml |
/contact | MapFallback |
What has improved?
- HTML is written directly in
.cshtmlfiles. - Routes are inferred from filenames.
- Razor expressions insert server-side values.
Program.csis substantially smaller.
Home and Privacy still repeat the document structure, head, stylesheet and navigation markup.
Next: PART 6 introduces Pages/Shared/_Layout.cshtml to remove this duplication.