Back to skills
SKILL.md
Razor Pages
ASecurityASP.NET Core Razor Pages patterns for server-rendered web apps.
- 8 stars
- 0 votes
- 0 copies
- 2 views
- Added September 8, 2026
Security analysis
100/100Pro scans all 2 files and shows the line behind each finding
npx -y skills add ngxtm/devkit --skill razor-pages --agent claude-codeAre you the author of Razor Pages?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ngxtm-razor-pages)---
name: Razor Pages
description: ASP.NET Core Razor Pages patterns for server-rendered web apps.
metadata:
labels: [razor, mvc, aspnet, web]
triggers:
files: ['**/*.cshtml', '**/*.cshtml.cs']
keywords: [PageModel, OnGet, OnPost, asp-for, asp-action]
---
# Razor Pages
## **Priority: P1 (OPERATIONAL)**
ASP.NET Core Razor Pages patterns for server-rendered web applications.
## Implementation Guidelines
- **PageModel**: Keep logic in PageModel, not in `.cshtml`. Use handlers (`OnGet`, `OnPost`).
- **Model Binding**: Use `[BindProperty]` for form data. `[FromQuery]` for query params.
- **Tag Helpers**: Use `asp-for`, `asp-action`, `asp-route-*` for type-safe HTML.
- **Partial Views**: Reusable UI components with `<partial>` tag helper.
- **View Components**: Complex reusable UI with server logic.
- **Layout**: Shared layout in `_Layout.cshtml`. Use sections for page-specific content.
- **TempData**: Flash messages with PRG (Post-Redirect-Get) pattern.
## Anti-Patterns
- **No logic in `.cshtml`**: Move to PageModel or View Components.
- **No `ViewBag`/`ViewData`**: Use strongly-typed models.
- **No inline CSS/JS**: Use external files with bundling.
- **No form without anti-forgery**: Always include `@Html.AntiForgeryToken()` or use `asp-antiforgery`.
## Code
```csharp
// Pages/Users/Create.cshtml.cs
public class CreateModel(IUserService userService, ILogger<CreateModel> logger) : PageModel
{
[BindProperty]
public CreateUserInput Input { get; set; } = new();
public List<SelectListItem> Roles { get; set; } = [];
public async Task OnGetAsync()
{
Roles = await GetRolesAsync();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
Roles = await GetRolesAsync();
return Page();
}
var result = await userService.CreateAsync(Input);
if (!result.IsSuccess)
{
ModelState.AddModelError(string.Empty, result.Error!);
Roles = await GetRolesAsync();
return Page();
}
TempData["Success"] = "User created successfully";
return RedirectToPage("./Index");
}
}
```
```html
@* Pages/Users/Create.cshtml *@
@page
@model CreateModel
<h2>Create User</h2>
@if (TempData["Error"] is string error)
{
<div class="alert alert-danger">@error</div>
}
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="mb-3">
<label asp-for="Input.Name" class="form-label"></label>
<input asp-for="Input.Name" class="form-control" />
<span asp-validation-for="Input.Name" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="Input.Email" class="form-label"></label>
<input asp-for="Input.Email" class="form-control" type="email" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="Input.RoleId" class="form-label"></label>
<select asp-for="Input.RoleId" asp-items="Model.Roles" class="form-select">
<option value="">Select a role</option>
</select>
<span asp-validation-for="Input.RoleId" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Create</button>
<a asp-page="./Index" class="btn btn-secondary">Cancel</a>
</form>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
```
## Reference & Examples
For page conventions, view components, and AJAX patterns:
See [references/REFERENCE.md](references/REFERENCE.md).
## Related Topics
aspnet-core | blazor | security
Files in this skill
- SKILL.md
- references/REFERENCE.md
Attribution
Comments
Loading comments…