ASP.NET Core CAPTCHA Integration
This recipe shows how to integrate TrustCaptcha into an ASP.NET Core application. The frontend setup is the same as for any other .NET application — this page focuses on the server-side validation.
The setup section gets you to a working integration in three small steps using a controller action directly. Below it, an optional refactor section shows the more reusable ASP.NET-Core-idiomatic approach (a custom action filter wired into the request pipeline).
Preparation
Section titled “Preparation”You should have already completed the following steps before you wire TrustCaptcha into your ASP.NET Core application.
Read Get-Started: Get a quick overview of the concepts behind TrustCaptcha and the integration process in get started.
Existing CAPTCHA: If you don’t have a CAPTCHA yet, sign in or create a new user account. Then create a new CAPTCHA.
1. Embed the frontend widget
Section titled “1. Embed the frontend widget”First, add the TrustCaptcha script to your page (see the JavaScript Guide for version pinning and self-hosting options).
Then place the <trustcaptcha-component> element inside your Razor form. The widget appends a hidden tc-verification-token field on submit, which your ASP.NET Core controller receives like any other form input.
<script type="module" src="https://cdn.trustcomponent.com/trustcaptcha/3.0.x/trustcaptcha.esm.min.js"></script>
<form asp-action="Submit" method="post"> @Html.AntiForgeryToken()
<label>Email</label> <input type="email" name="email" required />
<trustcaptcha-component sitekey="<your_site_key>"></trustcaptcha-component>
<button type="submit">Send</button></form>See the Widget Overview for the full property reference.
2. Install the .NET SDK
Section titled “2. Install the .NET SDK”dotnet add package TrustComponent.TrustCaptcha --version 3.0.03. Validate the token in your controller
Section titled “3. Validate the token in your controller”using Microsoft.AspNetCore.Mvc;using TrustComponent.TrustCaptcha;
namespace MyApp.Controllers;
public class ContactController : Controller{ [HttpPost] public async Task<IActionResult> Submit( [FromForm] string email, [FromForm(Name = "tc-verification-token")] string tcVerificationToken) { // In production, load from configuration: // builder.Configuration["Trustcaptcha:ApiKey"] var apiKey = "<your_api_key>";
try { var result = await TrustCaptcha.GetVerificationResultAsync(apiKey, tcVerificationToken);
if (!result.VerificationPassed || result.Score > 0.5) { ModelState.AddModelError("captcha", "CAPTCHA verification failed."); return View("Index"); } } catch (Exception) { ModelState.AddModelError("captcha", "CAPTCHA verification failed."); return View("Index"); }
// CAPTCHA passed — request data is safe to use. // ... your business logic ...
return RedirectToAction("ThankYou"); }}That’s it — the form is now protected. For real deployments, move the API key out of the source code (see the comment) and consider explicit failover handling — see Failover Behavior for the reasoning and a code template.
Refactor: extract to an action filter
Section titled “Refactor: extract to an action filter”If you protect more than one action, the most idiomatic ASP.NET Core approach is a custom action filter that runs before your action method. The CAPTCHA token check then becomes a single attribute on every protected action — no boilerplate inside the controller.
Configure the API key
Section titled “Configure the API key”{ "Trustcaptcha": { "ApiKey": "<your_api_key>" }}Create the filter
Section titled “Create the filter”using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Mvc.Filters;using TrustComponent.TrustCaptcha;
namespace MyApp.Filters;
public class TrustCaptchaActionFilter : IAsyncActionFilter{ private readonly IConfiguration _config; public TrustCaptchaActionFilter(IConfiguration config) => _config = config;
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var token = context.HttpContext.Request.Form["tc-verification-token"].ToString();
if (string.IsNullOrEmpty(token)) { context.Result = new BadRequestObjectResult("CAPTCHA verification failed."); return; }
try { var apiKey = _config["Trustcaptcha:ApiKey"]!; var result = await TrustCaptcha.GetVerificationResultAsync(apiKey, token);
if (!result.VerificationPassed || result.Score > 0.5) { context.Result = new BadRequestObjectResult("CAPTCHA verification failed."); return; } } catch (Exception) { context.Result = new BadRequestObjectResult("CAPTCHA verification failed."); return; }
await next(); }}Register the filter and create an attribute alias
Section titled “Register the filter and create an attribute alias”builder.Services.AddScoped<TrustCaptchaActionFilter>();using Microsoft.AspNetCore.Mvc;
namespace MyApp.Filters;
public class TrustCaptchaAttribute : ServiceFilterAttribute{ public TrustCaptchaAttribute() : base(typeof(TrustCaptchaActionFilter)) { }}Apply to your actions
Section titled “Apply to your actions”[HttpPost][TrustCaptcha]public IActionResult Submit([FromForm] string email){ // CAPTCHA already verified — the action only runs if it passed. return RedirectToAction("ThankYou");}A single [TrustCaptcha] attribute now opts any action into CAPTCHA verification.
Anti-forgery / CSRF. ASP.NET Core’s anti-forgery token (@Html.AntiForgeryToken() and [ValidateAntiForgeryToken]) and TrustCaptcha are independent layers — both should stay enabled. The CAPTCHA token does not replace the anti-forgery token.
Minimal APIs. For Minimal APIs, replace the action filter with an endpoint filter (IEndpointFilter). The same TrustCaptcha.GetVerificationResultAsync call applies — only the wrapper changes.
Singleton SDK instance. For configured usage (custom timeouts, proxy, custom API host), register a single TrustCaptcha instance in the DI container (built via TrustCaptcha.NewBuilder(...)) and inject it into the filter instead of using the static shortcut. See the DotNet Guide for the builder API.
Next steps
Section titled “Next steps”Once you have wired TrustCaptcha into your ASP.NET Core application, you can use TrustCaptcha to its full extent. However, we still recommend the following additional technical and organizational measures:
Security rules: You can find many security settings for your CAPTCHA in the CAPTCHA settings. These include, for example, authorized websites, CAPTCHA bypass for specific IP addresses, bypass keys, IP based blocking, geoblocking, individual difficulty and duration of the CAPTCHA, and much more. Learn more about the security rules.
Privacy & GDPR compliance: Include a passage in your privacy policy that refers to the use of TrustCaptcha. We also recommend that you enter into a data processing agreement with us to stay GDPR-compliant. Learn more about data protection.
Accessibility & UX: Customize TrustCaptcha to your website so that your website is as accessible as possible and offers the best possible user experience. More about accessibility.
Failover behavior: Decide how your backend should behave when our service is temporarily unreachable. This is particularly important for high-availability flows where blocking real users during an outage is worse than letting through a small amount of unverified traffic. Learn more about failover behavior.
Testing: If you use automated testing, make sure that the CAPTCHA does not block it. Learn more about testing.