reCAPTCHA не отображается на странице частичного просмотра MVC - PullRequest
0 голосов
/ 13 июня 2018

У меня проблемы с добавлением Google ReCAPTCHA на мою страницу.в макете я добавил Google Recaptcha js

_layout

     <title>@ViewBag.Title</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
        <script src='https://www.google.com/recaptcha/api.js'></script>
        <script type="text/javascript">
    <script type="text/javascript">

        $(document).ready(function () {

            $('#subject').on("change", function (e) {
                e.preventDefault();
                var selectedVal = $('#subject').val();
                $.ajax({
                    //  url: "/ContactUs/GetForm",
                    url: '@Url.Action("GetForm", "ContactUs")',
                    type: "POST",
                    data: { searchValue: selectedVal } ,
                    async: true,
                    success: function (data) {
                        $('#renderForms').empty();
                        $('#renderForms').append(data);

                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                        alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
                    }
                });
            });
 });

    </script>

, затем в своем индексе я выбираю, какую форму я хочу показать:

@Html.DropDownListFor(model => model.contactSelectListItems, new List<SelectListItem>
            {
                                new SelectListItem() {Text = "option1", Value="option1"},
                                new SelectListItem() {Text = "option2", Value="option2"},
                                new SelectListItem() {Text = "option3", Value="option3"},

            }, "--Choose--", new { id = "subject", @class= "dropdown-item" })
    </div>
    <div id="renderForms">
    </div>

в обоихна частичной странице есть форма, в которой я делаю что-то похожее, но с разными моделями представления:

    @using (Html.BeginForm("SendCustomerTeam", "ContactUs", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>CustomerTeamViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="container">
    <div class="form-group form-group-sm col-sm-6">
                    <div class="row">

                        @Html.LabelFor(model => model.Phone, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-sm-9">
                            @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Phone, "", new { @class = "text-danger" })
                        </div>
                    </div>
                </div>
                <div class="form-group form-group-sm col-sm-12">
                    <div class="row">
                        @Html.LabelFor(model => model.Inquiry, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-sm-12">
                            @Html.EditorFor(model => model.Inquiry, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Inquiry, "", new { @class = "text-danger" })
                        </div>
                    </div>
                </div>

                <div class="form-group form-group-sm col-sm-12">
                    <div class="row">
                        <div class="col-sm-12">
                            <div id="NotRobot">
                                <label>Are you Human?</label>                                
                                <div id='recaptcha' class="col-sm-12 g-recaptcha" 
                                     data-sitekey="@System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]"
                                     >
                                </div>
                                <div id="recaptchaMessage" data-verifyrecaptchatokenurl="@Url.Action("VerifyReCaptchaToken", "Home")" style="display:none;padding:10px;color:red;font-weight:bold;" class="error">You need to verify reCAPTCHA.</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="form-group form-group-sm col-sm-6">
                    <div class="row">
                        <div class="col-sm-9">
                            <input id="Send" type="submit" value="Send" class="btn btn-default" />
                        </div>
                    </div>
                </div> etc...

В моем контроллере я работаю так, как вы, я хотел бы обработать reCAPTCHA как вызов ajax, который мне еще предстоит выяснитькак это сделать.

public ActionResult Index()
        {
            ViewData["ReCaptchaKey"] = System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"];
//do something here
    }
    public static bool ReCaptchaPassed(string gRecaptchaResponse, string secret)
            {
                HttpClient httpClient = new HttpClient();
                var res = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret={secret}&response={gRecaptchaResponse}").Result;
                if (res.StatusCode != HttpStatusCode.OK)
                {
                    //logger.LogError("Error while sending request to ReCaptcha");
                    return false;
                }

                string JSONres = res.Content.ReadAsStringAsync().Result;
                dynamic JSONdata = JObject.Parse(JSONres);
                if (JSONdata.success != "true")
                {
                    return false;
                }

                return true;
            }
    [HttpPost]
            public ActionResult SendCustomerTeam(CustomerTeamViewModel model)
            {
                ContactViewModel contactModel = new ContactViewModel();
                contactModel.CustomerTeamModel = model;
                ViewData["ReCaptchaKey"] = System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"];

                if (ModelState.IsValid)
                {
                    if (!ReCaptchaPassed(
                        Request.Form["g-recaptcha-response"], // that's how you get it from the Request object
                        System.Configuration.ConfigurationManager.AppSettings["RecaptchaPrivateKey"]
                        ))
                    {
                        ModelState.AddModelError(string.Empty, "You failed the CAPTCHA, stupid robot. Go play some 1x1 on SFs instead.");
                        return View(contactModel);
                    }
                }

Моя проблема в том, что reCAPTCHA никогда не появляется на моей странице.

Изменить:

Я попробовал следующее упрощение, чтобы увидеть, еслиЯ мог бы найти проблему.

SimplePageViewModel

  public class simplePageViewModel
    {
        public string Name { get; set; }
    }

SimplePagePartialView

    @model Contact_Portal.Models.simplePageViewModel

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>simplePageViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="container">
            <div class="row">
                <div class="form-group form-group-sm col-sm-6">
                    <div class="row">
                        @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-sm-9">
                            @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                        </div>
                    </div>
                </div>
                <div class="form-group form-group-sm col-sm-12">
                    <div class="row">
                        <div class="col-sm-12">
                            <div id="NotRobot">
                                <label>Are you Human?</label>
                                <div id='recaptcha' class="col-sm-12 g-recaptcha" style="padding:10px;"
                                     data-sitekey="@System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]">
                                </div>
                                <div id="recaptchaMessage" data-verifyrecaptchatokenurl="@Url.Action("VerifyReCaptchaToken", "Home")" style="display:none;padding:10px;color:red;font-weight:bold;" class="error">You need to verify reCAPTCHA.</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-offset-2 col-md-10">
                        <input type="submit" value="Save" class="btn btn-default" />
                    </div>
                </div>
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

в контроллере. Я получаю частичное представление, показанное через эту строку

return PartialView("View", contactModel.simplePageModel);

Все еще сохраняется та же проблема.

Может быть, потому, что я показываю свою частичную страницу, содержащую reCAPTCHA, как часть вызова Jquery Ajax?как это:

  $(document).ready(function () {

        $('#subject').on("change", function (e) {
            e.preventDefault();
            var selectedVal = $('#subject').val();
            $.ajax({
                //  url: "/ContactUs/GetForm",
                url: '@Url.Action("GetForm", "ContactUs")',
                type: "POST",
                data: { searchValue: selectedVal } ,
                async: true,
                success: function (data) {
                    $('#renderForms').empty();
                    $('#renderForms').append(data);

                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
                }
            });
        });

Я сейчас перепробовал целый новый проект, где я упростил его до одного HTML-файла:

Index.cshtml

    <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script src="~/Scripts/modernizr-2.6.2.js"></script>
    <script src='https://www.google.com/recaptcha/api.js'></script>
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                </ul>
            </div>
        </div>
    </div>

    <div class="container body-content">
        <div id='recaptcha' class="col-sm-12 g-recaptcha" style="padding:10px;"
             data-sitekey="@System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]"></div>
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>

Все еще не видно, оно никогда не появляется.почему не работает?Может ли быть так, что ASP.NET MVC не поддерживается Recaptcha от Google?

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Ну, я нашел решение, я не доволен им, но оно работает.

в моем файле макета я сделал такой раздел:

 <script src="https://www.google.com/recaptcha/api.js" async defer></script>
 <script type="text/javascript">
     function enableBtn() {
                document.getElementById("subject").disabled = false;
            }
     $(document).ready(function () {
         document.getElementById("subject").disabled = true;
      });

    </script>

Затем в моемпредставление, которое я создал, это

<div class="g-recaptcha" data-sitekey="*********PublicKEY*************" data-callback="enableBtn"></div>

И, похоже, оно работает.

Я бы хотел, чтобы оно работало в частичном представлении, потому что теперь я должен иметь его независимо от того, что еще произойдети не только на подаче.

Я не знаю, смогу ли я проверить эту одну сторону сервера больше, так как она также находится вне моей формы.?Любой с лучшим вариантом будет приветствоваться.

РЕДАКТИРОВАТЬ:

Я нашел лучшее решение для меня.Я изменил свой вызов ajax так:

 $('#subject').on("change", function (e) {
                e.preventDefault();
                var selectedVal = $('#subject').val();
                $.ajax({
                    //  url: "/ContactUs/GetForm",
                    url: '@Url.Action("GetForm", "ContactUs")',
                    type: "POST",
                    data: { searchValue: selectedVal } ,
                    async: true,
                    success: function (data) {
                        $('#renderForms').empty();
                        $('#renderForms').append(data);

                        if (!debug) {
                            document.getElementById("Send").disabled = true;
                            grecaptcha.render('Captcha', {
                                'sitekey': '**********PublicKey*********',
                                'callback': function() {
                                    document.getElementById("Send").disabled = false;
                                },
                                'expired-callback': function() {
                                    //document.getElementById("subject").selectedIndex = 0;
                                    document.getElementById("Send").disabled = true;
                                    //document.getElementById("renderForms").innerHTML = "";
                                }


                            });

                        }
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                        alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
                    }
                });
            });

Теперь он работает так, как я планировал.По крайней мере, в части пользовательского интерфейса.

0 голосов
/ 13 июня 2018

Ваш сценарий src неверен:

<script src='https://www.google.com/recaptcha/api.js async defer'></script>

до

<script src='https://www.google.com/recaptcha/api.js'></script>

Также вы можете проверить консоль deveoper, если есть какая-либо ошибка?

...