Collect User Input
Step 1 — Read the Project's AGENTS.md
Check AGENTS.md for Interactivity Mode and Interactivity Scope. This determines which form patterns apply:
EditForm Setup
EditForm requires either Model or EditContext — never both.
Model-based (default)
This single pattern works in both SSR and interactive modes:
- In SSR:
FormNameidentifies the form,[SupplyParameterFromForm]binds POST data,??=initializes on GET. - In interactive:
@bind-Valueprovides two-way binding,[SupplyParameterFromForm]is ignored,FormNameis harmless.
EditContext-based (advanced)
Use when you need programmatic field tracking, dynamic validation rules, or manual EditContext.Validate() calls:
Submit Handlers
OnSubmit cannot combine with OnValidSubmit/OnInvalidSubmit.
Built-in Input Components
All input components use @bind-Value for binding. Always wrap text in a <label> or use id/for attributes for accessibility.
InputSelect with enum values
InputRadioGroup
Validation
Data annotations
Define validation rules on the model:
Add <DataAnnotationsValidator /> inside EditForm — without it, annotation attributes are silently ignored.
Display errors with:
<ValidationSummary />— all errors in a list<ValidationMessage For="() => Model!.FieldName" />— per-field inline errors
Custom validator component
For server-round-trip validation (uniqueness checks, business rules):
Usage in a form:
React to Input Changes (Interactive Only)
@bind:after
Run logic after a bound value changes:
@oninput for real-time filtering
SSR-Specific Patterns
These apply when the form renders in Static SSR (mode = None, or per-page without @rendermode).
SupplyParameterFromForm
Binds POST data to a property on form submission:
Critical: The ??= in OnInitialized is required. On GET the property is null — ??= creates the model. On POST the framework populates it — ??= preserves the posted values.
FormName — multiple forms on one page
Each form needs a unique FormName:
Match [SupplyParameterFromForm] to its form:
Enhanced navigation for forms
Add Enhance for SPA-like form submissions without full page reload:
Enhanced forms submit via fetch, patch the DOM, and preserve scroll position. The page stays interactive-feeling even in SSR.
Plain HTML forms
When using raw <form> instead of EditForm in SSR, add the antiforgery token manually:
EditForm includes the antiforgery token automatically.
File Upload
InputFile works in interactive modes only — not in Static SSR.
Stream size limits:
- Server: Default ~30 KB SignalR message size. Call
OpenReadStream(maxAllowedSize)to increase. Large files stream over the circuit. - WebAssembly: File is read in the browser. No SignalR limit, but memory constrained.
For multiple files:
Prevent Double Submission
Disable the submit button while processing:
Custom Validation CSS
Replace the default valid/invalid CSS classes:
Apply to the form:
Don'ts
- Don't use
@bindor@oninputin Static SSR forms — they require interactivity. Use[SupplyParameterFromForm]andFormName. - Don't forget
Model ??= new()inOnInitialized— the model is null on GET, populated on POST. - Don't use
OnSubmittogether withOnValidSubmit/OnInvalidSubmit— they're mutually exclusive. - Don't omit
<DataAnnotationsValidator />— validation attributes are silently ignored without it. - Don't omit
FormNamein SSR when a page has multiple forms — both forms will fire on any submission. - Don't use
InputFilein Static SSR — it requires an interactive render mode. - Don't use both
ModelandEditContexton anEditForm— pick one. - Don't forget
<AntiforgeryToken />in plain<form>elements — the server rejects the POST without it.


