dotnet add package CWaptcha
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
{
"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.
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();
// Startup.cs — ConfigureServices
services.AddCWaptcha(Configuration.GetSection("CWaptcha"));
// Startup.cs — Configure (BEFORE app.UseUmbraco())
app.UseCWaptcha();
<!-- 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.
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>
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
}
}