-
Notifications
You must be signed in to change notification settings - Fork 0
Forms Postbacks and Antiforgery
When a resolved page receives POST, Imp calls IAsyncPostable.PostbackAsync when implemented; otherwise it calls IPostable.Postback. Rendering continues afterward.
Prefer IAsyncPostable for modern ASP.NET Core applications.
builder.Services.AddAntiforgery();Inject IAntiforgery into the page, render a token, and validate every state-changing request. Imp does not add antiforgery automatically.
[PageTemplate("MySite.PageTemplates.Tasks.htm")]
public sealed class Tasks(TaskStore store, IAntiforgery antiforgery)
: BasePage, IAsyncPostable
{
private string message;
public Task Antiforgery(TextWriter output, DynamicContentArgs args)
{
var tokens = antiforgery.GetAndStoreTokens(Request.HttpContext);
var name = HtmlEncoder.Default.Encode(tokens.FormFieldName);
var value = HtmlEncoder.Default.Encode(tokens.RequestToken);
return output.WriteAsync(
$"<input type=\"hidden\" name=\"{name}\" value=\"{value}\" />");
}
public async Task PostbackAsync(HttpResponse response)
{
try
{
await antiforgery.ValidateRequestAsync(Request.HttpContext);
var form = await Request.ReadFormAsync();
store.Add(form["title"].ToString());
message = "Task added.";
}
catch (AntiforgeryValidationException)
{
response.StatusCode = StatusCodes.Status400BadRequest;
message = "The form expired. Reload and try again.";
}
}
}Template:
<form method="post">
<Dynamic.Antiforgery />
<label for="title">Task</label>
<input id="title" name="title" maxlength="120" required="required" />
<button type="submit">Add</button>
</form>Query properties are bound before PreRender and postback handling. Form fields are not bound to properties; read them through Request.ReadFormAsync().
Validate on the server even when HTML attributes provide client-side validation:
- required values and maximum lengths;
- number/date ranges;
- IDs and record existence;
- user ownership and authorization;
- allowed action names;
- upload type and size, if enabled.
Do not display exception text that can contain secrets or internal details. Return a safe validation message and log the diagnostic separately.
A hidden action field is a simple way to share one page postback:
<input type="hidden" name="action" value="delete" />Use an allow-list switch and verify the target belongs to the current user. Treat every form field as untrusted.
Imp normally renders the page after PostbackAsync. This is convenient for inline validation but browser refresh may resubmit the form. If implementing post/redirect/get, test the response carefully because the Imp lifecycle proceeds to rendering after the postback. A dedicated application middleware or a future framework short-circuit feature may be preferable for complex workflows.
Imp is MIT licensed. See the source and Todo sample on GitHub.
Imp
Templates
Application integration
- Forms and antiforgery
- Dependency injection
- Authentication and secure pages
- Static assets and CDN paths
- Configuration reference
Help and reference