The .cshtml extension identifies Razor files that combine HTML elements with embedded C# code. Razor views use these files to generate response HTML from controller-provided model data. section 3.2.8
Use the extension in two closely related ASP.NET Core patterns:
- Name a controller view after its action, such as ListResponses.cshtml in Views/Home; the view renders the model passed by View. section 3.2.8
- Create Razor Pages such as Pages/Index.cshtml; add @page first, select a page model with @model, and define supporting code with @functions. section 23.2.2
- Keep the distinction clear: the same extension does not determine the hosting model; @page prevents a Razor Page from being treated as a controller view. section 23.2.2
Rendering filtered responses
A ListResponses.cshtml view declares @model IEnumerable<PartyInvites.Models.GuestResponse> and uses @foreach to turn each response into a table row. The controller supplies only guests whose WillAttend value is true. section 3.2.8
Listing 3.16 Displaying data in the ListResponses.cshtml file in the Views/Home folder
@model IEnumerable<PartyInvites.Models.GuestResponse>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Responses</title>
</head>
<body>
<h2>Here is the list of people attending the party</h2>
<table>
<thead>
<tr><th>Name</th><th>Email</th><th>Phone</th></tr>
</thead>
<tbody>
@foreach (PartyInvites.Models.GuestResponse r in Model!) {
<tr>
<td>@r.Name</td>
<td>@r.Email</td>
<td>@r.Phone</td>
</tr>
}
</tbody>
</table>
</body>
</html>
Inspect a complete controller-view file showing model declaration, Razor iteration, HTML output, and property expressions. section 3.2.8
Listing 23.4 The contents of the Index.cshtml file in the Pages folder
@page
@model IndexModel
@using Microsoft.AspNetCore.Mvc.RazorPages
@using WebApp.Models;
<!DOCTYPE html>
<html>
<head>
<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="bg-primary text-white text-center m-2 p-2">
@Model.Product?.Name
</div>
</body>
</html>
@functions {
public class IndexModel : PageModel {
private DataContext context;
public Product? Product { get; set; }
public IndexModel(DataContext ctx) {
context = ctx;
}
public async Task OnGetAsync(long id = 1) {
Product = await context.Products.FindAsync(id);
}
}
}
Compare a Razor Page file that combines @page, @model, HTML markup, and an inline PageModel implementation. section 23.2.2
