1

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

4

1 回答 1

1

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.

于 2013-03-13T09:16:58.763 回答