0

I am trying to call a Javascript function using C# in Content Grabber. (Content Grabber is a web scraping software).

The Javascript code is this:

$.definePage({
    idRecaptcha: null,

    init: function() {},

    carregarReCaptcha: function() {
        if(page.idRecaptcha == null) {
            var sitekey = $("#reCaptchaPublicKey").val();
            page.idRecaptcha = grecaptcha.render($("#tecRecaptcha")[0], {
                'callback' :  page.verifyCallback,
                'sitekey': sitekey
            });
        }
    },

    verifyCallback: function(response) {
        if(response) {
            $("#form").submit();
        }
    }
});

var onloadCallback = function() {
    page.carregarReCaptcha();
}

The function I want to call is "verifyCallback". This function essentially submits the recaptcha token, which will verify if the token I have entered is correct or not.

In my Content Grabber agent, I want to call this function, and I have this code, but it's giving me an error:

using System;
using System.Web.UI;
using Sequentum.ContentGrabber.Api;
public class Script
{
    //See help for a definition of CustomScriptArguments.
    public static CustomScriptReturn CustomScript(CustomScriptArguments args)
    {
        // retrieve page from current handler
        var page = System.Web.HttpContext.Current.CurrentHandler as Page;

        if (page == null)
        {
            // do something, e.g. throw exception
            return CustomScriptReturn.Pause();
        }

        // Place your script code here.
        // Return empty for no special action.
        string response = args.DataRow["Captcha"];
        string script = "page.verifyCallback('" + response + "');";

        // call ClientScript from existing page instance
        page.ClientScript.RegisterStartupScript(page.GetType(), "page.verifyCallback", script, true);

        return CustomScriptReturn.Empty();
    }
}

When I compile it, it's returning this error:

Object reference not set to an instance of an object.

It looks like I can't just delete object sender, EventArgs e

I'm not really familiar with JS or C#, so I would appreciate any help I can get. Thank you so much!

  • You've now got a method defined within a method - this isn't allowed in C#. Remove the `protected void callback(object sender, EventArgs e)` and associated braces from the CustomScript method. You are also returning from your CustomScript method before any of the other code runs. Move your `return` statement to the end of the CustomScript method. – JTech Nov 06 '18 at 06:35
  • Thank you for the edit. It compiled well, but when I ran it, I got the error: Object reference not set to an instance of an object. Is it because we omitted the declaration "object sender, EventArgs e"? – Rachelle Ann Facistol-Mata Nov 06 '18 at 06:49
  • Its difficult to say without you giving us the line number from the Stack Trace in the runtime error output. Looking at the code, it could be because the `page` object is null. Your code checks to see if its null, but then doesn't do anything about it and the code is allowed to continue... – JTech Nov 06 '18 at 06:51
  • I see. I added a pause action if the page is null. I ran the script, and my agent did not pause (so I assume page is not null), but I still get the object error. About the line number, unfortunately, I can't find it. When I'm compiling it, no error registers. It's just when I run it with the agent that the error appears, and there's no note of the line number in the error message. – Rachelle Ann Facistol-Mata Nov 06 '18 at 07:06

2 Answers2

1

The problem occurs because you're trying to use ClientScript instance from a class which not inherited from System.Web.UI.Page (base class for code-behind pages). As long as you have access to HttpContext.Current, you can retrieve Page instance from its handler property (i.e. CurrentHandler) and use ClientScript as in example below:

public class Script
{
    //See help for a definition of CustomScriptArguments.
    public CustomScriptReturn CustomScript(CustomScriptArguments args, object sender, EventArgs e)
    {
        // retrieve page from current handler
        var page = HttpContext.Current.CurrentHandler as Page;

        if (page == null)
        {
            // do something, e.g. throw exception
        }

        // Place your script code here.
        // Return empty for no special action.
        string response = args.DataRow["Token"];
        string script = "verifyCallback('" + response + "');";

        // call ClientScript from existing page instance
        page.ClientScript.RegisterStartupScript(page.GetType(), "verifyCallback", script, true);
        return CustomScriptReturn.Empty();
    }
}

Update:

As for explaining the second error after edit, it occurred because you're declaring a method named callback inside CustomScript method, which is not valid (and the return statement must be on the last). If the sender and EventArgs handlers are unnecessary then simply omit them. Here is an example to properly return CustomScriptReturn:

public static CustomScriptReturn CustomScript(CustomScriptArguments args)
{
    // retrieve page from current handler
    var page = System.Web.HttpContext.Current.CurrentHandler as Page;

    if (page == null)
    {
        // do something, e.g. throw exception
    }

    // Place your script code here.
    // Return empty for no special action.
    string response = args.DataRow["Captcha"];
    string script = "page.verifyCallback('" + response + "');";

    // call ClientScript from existing page instance
    page.ClientScript.RegisterStartupScript(page.GetType(), "page.verifyCallback", script, true);

    return CustomScriptReturn.Empty();
}

Related issue:

An object reference is required for the non-static field, method, or property 'System.Web.UI.Page.ClientScript.get'

Tetsuya Yamamoto
  • 21,982
  • 5
  • 34
  • 53
  • Thank you @tetsuya for you quick response. I have applied all of your suggestions and was able to compile it without error. However, when I ran it in Content grabber, I get this error: Error executing custom script. Error: The method CustomScript must have exactly one parameter of type CustomSriptArguments. It appears the customScript can't have the declarations "object sender, EventArgs e" I tried moving these definitions inside the customScript, but it's giving even more errors. Please see the original question. I have modified the script there. Again, thank you so much! – Rachelle Ann Facistol-Mata Nov 06 '18 at 06:20
  • Edited with some explanation about method you're using and placement of `return` statement. – Tetsuya Yamamoto Nov 06 '18 at 06:39
  • Thank you for the edit. It compiled well, but when I ran it, I got the error: Object reference not set to an instance of an object. Is it because we omitted the declaration "object sender, EventArgs e"? – Rachelle Ann Facistol-Mata Nov 06 '18 at 06:49
  • That's `NullReferenceException`, but sounds unrelated with absence of `sender` and `EventArgs` (they're used for event handlers). Try checking where and when the exception being thrown. – Tetsuya Yamamoto Nov 06 '18 at 07:02
  • I see. I added a pause action if the page is null. I ran the script, and my agent did not pause (so I assume page is not null), but I still get the object error. About the line number, unfortunately, I can't find it. When I'm compiling it, no error registers. It's just when I run it with the agent that the error appears, and there's no note of the line number in the error message. – Rachelle Ann Facistol-Mata Nov 06 '18 at 07:07
  • If that `NullReferenceException` is a runtime error, try debug with the agent enabled. You can enable debugging feature of the web server or attach debugger to process handler and return detailed error message (check [this article](https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-enable-debugging-for-aspnet-applications)). – Tetsuya Yamamoto Nov 06 '18 at 07:21
  • @TetsuyaYamamoto The HttpContext.Current is == null , so the var page = ... stuff returns an object null error. It doesnt even get to if(page == null) , so it doesnt even pause . As far as the rest of stack says its because its running on a separate thread. – Luka Kostic Nov 06 '18 at 09:29
  • You're stated that the process running in separate thread, then it matches [this issue](https://stackoverflow.com/questions/22323448/why-httpcontext-current-always-null-in-user-defined-class-in-asp-net-mvc). Consider read [this issue](https://stackoverflow.com/questions/8925227/access-httpcontext-current-from-different-threads) for multi-threaded scenario. – Tetsuya Yamamoto Nov 06 '18 at 09:37
1

In addition to @Tetsuya's answer, it looks like you'll have an issue with the Javascript you're passing to RegisterStartupScript.

I don't think you'll be able to just call "verifyCallback" because that is a function defined within the scope of the $.definePage({}) call.

So you'll need to dig deeper into that and find out if the verifyCallback function is exposed publically.

Based on this code:

var onloadCallback = function() {
    page.carregarReCaptcha();
}

I'd say you'd need to call:

page.ClientScript.RegisterStartupScript(page.GetType(), "page.verifyCallback", script, true);
JTech
  • 3,076
  • 5
  • 37
  • 46
  • Thank you @JTech for you quick response. I have applied all of your suggestions and was able to compile it without error. However, when I ran it in Content grabber, I get this error: Error executing custom script. Error: The method CustomScript must have exactly one parameter of type CustomSriptArguments. It appears the customScript can't have the declarations "object sender, EventArgs e" I tried moving these definitions inside the customScript, but it's giving even more errors. Please see the original question. I have modified the script there. Again, thank you so much! – Rachelle Ann Facistol-Mata Nov 06 '18 at 06:20