DayByDay
DayByDay

Reputation: 84

Running Task.Factory.StartNew() results in System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult] showing up on the returned view (ASP.NET MVC3)

Our goal is to get Google Recaptcha V3 working on a single form on an MVC3 .NET4.5 project. However, I'm struggling to make this work due to the async request to Google for the Recaptcha score.

FE is set up. I set the new token to a hidden field and send the token to the controller. Then, I run this async task and make the validation request to Google. The response comes back with the success message and the score.

I thought I finally had it working using Task.Factory.StartNew(), but it results in System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult] showing up on the returned view.

Note: It is not an option to upgrade legacy ASP.NET MVC3 project to MVC4.

The hidden field in the view: `

// Other code

@Html.HiddenFor(model => model.Token, new { id="SubscriptionFormModelToken"})

// Other code
`

The token gets set to the hidden field in the JS: ` var your_site_key = '@System.Configuration.ConfigurationManager.AppSettings["ReCaptchaV3PublicKey"]'; console.log('your_site_key', your_site_key);

    $(function () {
        grecaptcha.ready(function () {

        grecaptcha.execute('@System.Configuration.ConfigurationManager.AppSettings["ReCaptchaV3PublicKey"]', { action: 'submit' }).then(function (token) {
            // Set token to hidden field for BE validation
            console.log('newest token:', token);

            var subscriptionFormModelElement = document.getElementById("SubscriptionFormModelToken");
            subscriptionFormModelElement.value = token;
            console.log('subscriptionFormModelElement:', subscriptionFormModelElement);


        });
    });
    })
 </script>

`

Pass the token in and run the task: ` [HttpPost] public async Task SubmitSubscriptionForm(SubscriptionFormModel model, FormCollection collection) {

        //Fetch Google Recaptcha result
        var captchaObject = Task.Factory.StartNew(() => GoogleCaptchaService.VerifyToken(model.Token));

        var captchaResult = captchaObject.Result.Result;

        if (!captchaResult)
        {
            model.RecaptchaResponseIsGood = false;
            return PartialView("Subscription/_SubscriptionForm", model);
        }
        
        // A lot of other code runs to save the Form Results to the db if captchaResult is successful. 
    }

`

Task runs through. Response comes back with success/fail and the score: `public class GoogleCaptchaService {

    //Google Recaptcha V3 server-side validation
    public static async Task<bool> VerifyToken(string token)
    {
        try
        {
            var url = $"https://www.google.com/recaptcha/api/siteverify?secret={@System.Configuration.ConfigurationManager.AppSettings["ReCaptchaV3PrivateKey"]}&response={token}";

            using (var client = new HttpClient())
            {

                var httpResult = await client.GetAsync(url);

                var responseString2 = httpResult.Content.ReadAsStringAsync().Result;


                if (!httpResult.IsSuccessStatusCode)
                {
                    return false;
                }

                var googleResult = JsonConvert.DeserializeObject<CaptchaResponse>(responseString2);

                if (googleResult.Success && googleResult.Score >= 0.5)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        catch (Exception e)
        {
            return false;
        }
    }

}`

After all this, the form submits and a partial view is returned, but this appears on the view: System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult].

Upvotes: 0

Views: 73

Answers (0)

Related Questions