Pergunta

I've implemented ReCaptcha in MVC3 using ReCaptcha.net NuGet package http://recaptchanet.codeplex.com/wikipage?title=How%20to%20Use%20Recaptcha%20in%20an%20ASP.NET%20MVC%20Web%20Application. All working well, except I'd like to see if I can implement this as Async as it is sometimes quite slow, and we may have some volume on these pages.

The instructions say

RecaptchaVerificationResult recaptchaResult = await recaptchaHelper.VerifyRecaptchaResponse();

if (recaptchaResult != RecaptchaVerificationResult.Success)
{
    ModelState.AddModelError("", "Incorrect captcha answer.");
}

however, this is using the MVC4 await syntax. Is there a way I can use this method within the MVC3 async framework?

I did try a quick hack, converting the controller to AsyncController naming the method with an Async suffix and wrapping the entire action in a Task.Factory.StartNew(() => { ... }); while using the non-async syntax, but RecaptchaVerificationHelper recaptchaHelper = this.GetRecaptchaVerificationHelper(); complains about a lack of HTTPContext.

So, can anyone help me with doing ReCaptcha asynchronously in MVC3

Foi útil?

Solução

In the end, I've dropped using the NuGet package, and simply process the captcha's using the code below, binding the recaptcha fields in the controller method.

    public bool ProcessCaptcha(string recaptcha_challenge_field, string recaptcha_response_field)
    {

        const string verifyUrl = "http://www.google.com/recaptcha/api/verify";
        var res = true;
        var ip = Request.UserHostAddress;
        if (ip == "::1") ip = "127.0.0.1";
        var myParameters = string.Format("privatekey={0}&remoteip={1}&challenge={2}&response={3}", Config.CaptchPriv, ip, recaptcha_challenge_field, recaptcha_response_field);
        using (WebClient wc = new WebClient())
        {
            wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
            string HtmlResult = wc.UploadString(verifyUrl, myParameters);
            var split = HtmlResult.Split('\n');
            if (split[0] == "false") res = false;
        }

        return res;
    }

With this in place, I split my original controller method into a Async/Completed pair, and wrapped the work it does in Task.Factory.StartNew(() => { ... }), following the pattern outlined here http://www.deanhume.com/Home/BlogPost/mvc-asynchronous-controller---the-basics/67 which seems to work perfectly.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top