Search code examples
asp.net-corerazor-pagesbotdetect

BotDetect and ASPNET Razor Pages is not validating


I have decided to use BotDetect Captcha in my project to stop spam, however, I have not been able to check if the user has entered the correct captcha since Razor Pages doesn't support Filters.

On their site, they say to use this attribute to check if the captcha is valid

[CaptchaValidationActionFilter("CaptchaCode", "ExampleCaptcha", "Wrong Captcha!")]

However, razor pages doesn't allow attributes on page methods.

Digging into the source code of the attribute, I found this

MvcCaptcha mvcCaptcha = new MvcCaptcha(this.CaptchaId);
if (mvcCaptcha.IsSolved) { }

However when I tried that code directly in the OnPost method, mvcCaptch.IsSolved always returns false.

Checking the session variables also shows all of the BDC_ values required for this control to work so I've hit a wall here. Hoping someone could help me out. Thanks.

Official docs if it helps, although, I could'nt find any reference to Razor Pages on the site https://captcha.com/mvc/mvc-captcha.html


Solution

  • I found there is an attribute CaptchaModelStateValidation attribute you can apply to a Razor page model property that is bound to the captcha code input. This way you get the validation automatically in the ModelState.

    Here is a sample model that validates the captcha.

    public class CaptchaValidatorModel : PageModel
    {
       public void OnPost()
       {
          if (ModelState.IsValid)
          {
             // Perform actions on valid captcha.
          }
       }
    
       [BindProperty]
       [Required] // You need this so it is not valid if the user does not input anything
       [CaptchaModelStateValidation("ExampleCaptcha")]
       public string CaptchaCode { get; set; }
    }
    

    The page uses the code provided in the documentation sample.

    @page
    @model CaptchaWebApplication.Pages.CaptchaValidatorModel
    @{
       ViewData["Title"] = "Captcha";
    }
    <form method="post">
       <label asp-for="CaptchaCode">Retype the code from the picture:</label>
       <captcha id="ExampleCaptcha" user-input-id="CaptchaCode" />
       <div class="actions">
          <input asp-for="CaptchaCode" />
          <input type="submit" value="Validate" />
          <span asp-validation-for="CaptchaCode"></span>
          @if ((HttpContext.Request.Method == "POST") && ViewData.ModelState.IsValid)
          {
             <span class="correct">Correct!</span>
          }
       </div>
    </form>