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();
Classic hosting (Startup.cs — Umbraco 13)
// Startup.cs — ConfigureServices
services.AddCWaptcha(Configuration.GetSection("CWaptcha"));

// Startup.cs — Configure (BEFORE app.UseUmbraco())
app.UseCWaptcha();
Call UseCWaptcha() before app.UseUmbraco() so CWaptcha's endpoints are registered before Umbraco's router.

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.

Using jQuery AJAX? Add data-cwaptcha-badge to your form to display the shield badge next to the submit button on page load — no extra JavaScript required.

6. Trust badge (optional)

Add a badge attribute to your form to show a shield badge next to the submit button on page load — no extra JavaScript. Works for standard forms and jQuery AJAX forms alike.

<!-- neutral gray, centered under button row (default) -->
<form method="post" data-cwaptcha data-cwaptcha-badge>
    <button type="submit">Send</button>
</form>

<!-- green pill with custom label -->
<form method="post" data-cwaptcha data-cwaptcha-badge-option5="Korumalı">
    <button type="submit">Gönder</button>
</form>

<!-- brand-color, jQuery AJAX form -->
<form id="ajaxForm" data-cwaptcha-badge-option2="Protected">
    <button type="submit" style="background:#1a73e8;color:#fff">Submit</button>
</form>
5 badge styles — the attribute name selects the style; the value is the label text (any language, empty value → "Protected"):data-cwaptcha-badge — neutral gray, centered under button row (default)data-cwaptcha-badge-option2="text" — brand-color tint, centereddata-cwaptcha-badge-option3="text" — uppercase signature, right-aligneddata-cwaptcha-badge-option4="text" — minimal, inline in button rowdata-cwaptcha-badge-option5="text" — green pill, stacked under button

7. 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.