Docs / Quick Start
Documentation

Quick Start

From zero to a protected form in under five minutes.

1. Install the package

dotnet add package CWaptcha

2. Set the secret key

Never commit SecretKey to source control. Use user-secrets in development and environment variables in production.

# Development
dotnet user-secrets set "CWaptcha:SecretKey" "your-32-char-minimum-secret-here"

# Production (IIS — set in system environment variables or web.config)
CWaptcha__SecretKey=your-secret-here

3. Configure (appsettings.json)

{
  "CWaptcha": {
    "LicenseKey":        "CW-...",         // from CWaptcha.KeyGen
    "Domain":            "example.com",    // must match the licensed domain
    "NonceTtlSeconds":   300,
    "HoneypotFieldName": "cw_hp_email",
    "ProtectedPaths":    [ "/Contact" ],
    "RequireHttps":      true
  }
}

List the POST routes you want the middleware to intercept automatically in ProtectedPaths. Leave it empty if you're using [CWaptchaValidation] on controller actions instead.

Keep LicenseKey out of source control — use user-secrets (dev) or an environment variable (CWaptcha__LicenseKey) in production. Without a key, CWaptcha logs a warning but still protects forms.

4. Register and use (Program.cs)

using CWaptcha.AspNetCore.Extensions;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddCWaptcha(builder.Configuration.GetSection("CWaptcha"));

var app = builder.Build();
app.UseStaticFiles();
app.UseCWaptcha();   // ← before MapRazorPages / MapControllers
app.MapRazorPages();
app.Run();

5. Add the script and protect your form

<!-- Add data-cwaptcha to the form you want to protect -->
<form method="post" data-cwaptcha>
    <input name="Name"  required />
    <input name="Email" type="email" required />
    <button type="submit">Send</button>
</form>

<!-- Include cwaptcha.js before </body> -->
<script src="/cwaptcha/cwaptcha.js" data-honeypot="cw_hp_email"></script>

That's it. The middleware will intercept the POST, validate the CAPTCHA, and pass valid requests through to your handler. Invalid requests receive a 400 response automatically.

6. Your handler needs no changes

public class ContactModel : PageModel
{
    [BindProperty] public string Name    { get; set; } = "";
    [BindProperty] public string Email   { get; set; } = "";

    public void OnGet() { }

    public void OnPost()
    {
        // Only ever reached if CWaptcha passed validation
    }
}
Using jQuery AJAX or vanilla fetch? See the integration wizard for the CWaptcha.sign() API and the [CWaptchaValidation] filter attribute.