Demo 4 — [CWaptchaValidation] + standard form submit

The form POSTs to an MVC controller action decorated with [CWaptchaValidation]. No AJAX, no ProtectedPaths config entry needed — protection is per-action via the attribute.

How it works: data-cwaptcha on the form triggers cwaptcha.js to intercept the submit event, inject the CAPTCHA fields into the form, then allow the browser to POST normally. On success the controller redirects back here; on failure the browser shows the JSON error response.

Active CWaptcha settings (demo info panel)
Cooldown120s base → ×2 per retry during lockout → capped at 3600s
Challenge fallbackBypassBehavior, window 120s, tolerance 6px
Min fill time3000 ms
Require mouse movementTrue
Anomaly trigger threshold0.75
Response modeTooManyRequests429
Behavior memory TTL3600 s
Honeypot fieldcw_hp_email
Nonce TTL300 s

A behavior_flagged rejection right after a successful submit means the cooldown above is active — each retry during the lockout extends it. Wait it out (the AJAX/fetch demos show the remaining seconds), or lower CWaptcha:Behavior:CooldownSeconds in appsettings.json while testing.






Show server-side code
[Route("contact-mvc")]
public sealed class ContactMvcFormController : Controller
{
    [HttpPost("submit")]
    [CWaptchaValidation]
    public IActionResult Submit(
        [FromForm] string? name,
        [FromForm] string? email,
        [FromForm] string? message)
        => Redirect($"/ContactMvc?success=1&name={Uri.EscapeDataString(name ?? "")}" +
                    $"&email={Uri.EscapeDataString(email ?? "")}" +
                    $"&message={Uri.EscapeDataString(message ?? "")}");
}