Home > Blockchain >  How to call non static method from ajax, asp.net webforms
How to call non static method from ajax, asp.net webforms

Time:06-17

in the template I have set and interval every 60 seconds to call backend method to update something in the page

           setInterval(function () {
                $.ajax({
                    url: 'CameraDashboard.aspx/LoadNotifications',
                    type: 'POST',
                    success: function () {
                        console.log('success')
                    },
                    error: function () {
                        console.log('error')
                    }
                })
            }, 60000);

in the code behind

    [WebMethod]
    protected void LoadNotifications()
    {
          some code ...
    }

the response is always server error

I tried to use static method using this method but also get error of instantiating object to use this mtheod

CodePudding user response:

When you do a ajax call, it should work. So, we have to fix the error first.

Once that is done, then we have to address the 2nd huge issue:

An ajax call or web method on a web page is a "static" member of that class. Since there is no post-back, then ZERO update of the page controls can occur. Since no post-back has occurred, then any and all controls on the web page of course cannot be modified, nor are they available in the code behind for that web method. Keep in mind that ALSO the viewstate is not available at this point in time either (session() is available however).

So while the ajax call and the web method can be on (and in) the same web page, that web method cannot modify or change controls on the page, since no post-back has occured.

Possible solutions:

Have the ajax call return the values you want, and then the js code can update and modify and set the controls on the web page.

Or, you can drop in a asp.net timer, and put the controls (and timer) inside of a update panel. This will result in what we call a partial post-back, and ONLY that part of the web page (inside the update panel) will be set to the server, and thus as a result only updated on the web page.

It is of course significantly less work to use a update panel, since then you don't have to write any client side (js) code, and the whole process is wired up automatic for you.

Ok, with the above crystal clear in our minds?

The web method as noted can be placed in the same web page. You do not need say for example to create a seperate web page (ascx), and put your web methods into that seperate page. however, the results are quite much the same, since as noted, without a post-back, then no update of controls, or even reading/grabbing/using/seeing controls on the web page can occur in that web method, and the reason as noted is the web page still remains sitting on the users desktop.

If you REALLY need the web method to update some controls on the page, then as noted, have the js client code update such controls, or as noted, dump the ajax call, and introduce a update panel. The results will be quite much the same. (to be fair, the ajax call is somewhat "lighter" in terms of payload, since the update panel DOES send the viewstate on updates.

so, lets do this ajax call.

So, our markup - first name, last name, and then we call a method to combine the two into a full name (our web method).

So, this markup:

        Enter First Name: <asp:TextBox ID="txtFirst" runat="server" ClientIDMode="Static"></asp:TextBox>
        <br />

        Enter First Name: <asp:TextBox ID="txtLast" runat="server" ClientIDMode="Static"></asp:TextBox>

        <br />
        <br />
        <asp:Button ID="Button1" runat="server" Text="combine first and last name"
            OnClientClick="mycombine();return false"
            />
        <br />
        <br />
        Result of ajax call <asp:TextBox ID="txtFullName" runat="server" ClientIDMode="Static"></asp:TextBox>


        <script>

            function mycombine() {

                MyFirstName = $("#txtFirst").val()
                MyLastName = $("#txtLast").val()
                
                $.ajax({
                    type: "POST",
                    url: "AjaxTest2.aspx/CombineName",
                    data: JSON.stringify({ FirstName: MyFirstName, LastName: MyLastName}),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                        success: function (myresult) {
                        // put result of method call into txtResult
                        // ajax data is ALWAYS ".d" - its a asp.net thing!!!
                        $("#txtFullName").val(myresult.d)
                    },
                    error: function (xhr, status, error) {
                        var errorMessage = xhr.status   ': '   xhr.statusText
                        alert('Error - '   errorMessage)
                    }
                });
            }

        </script>

And our code behind:

note: using System.Web.Services;

public partial class AjaxTest2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    
    [WebMethod()]
    public static string CombineName(string FirstName, string LastName)
    {
        string MyResult = "";

        MyResult = FirstName   " "   LastName;

        return MyResult;
    }

So, when we run, we get this:

enter image description here

So, depending on what you want to update on the page, either the above ajax call, or we can use a update panel.

We could do above with a update panel. You also not see and experience a full page post-back, and it is a whole lot less work. It really comes down to what you want to do.

but, do keep in mind in above:

The web method is considered a static member - it really does not have use of any controls on the page - since there is no post-back, and thus you have to mark the web method as "public static". And as such, then it can't see, get, grab, view or use controls on the page, and no use of viewstate is also avaialble. So, any update of the page will have to be passed back, and done client side.

Of course, the other way is the simple use of a update panel, and we would simple drop all 3 text box, the button inside of the update panel. Drop in a script manager, and thus no client side js code would have to be written.

Try both - see which you like.

so, the lazy bones way?

Lets do this with a update panel.

So, our markup is now this:

        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
            Enter First Name: <asp:TextBox ID="txtFirst" runat="server" ClientIDMode="Static"></asp:TextBox>
            <br />

            Enter First Name: <asp:TextBox ID="txtLast" runat="server" ClientIDMode="Static"></asp:TextBox>

            <br />
            <br />
            <asp:Button ID="Button1" runat="server" Text="combine first and last name"

                OnClick="Button1_Click"
                />
            <br />
            <br />
            Result of ajax call <asp:TextBox ID="txtFullName" runat="server" ClientIDMode="Static"></asp:TextBox>
            </ContentTemplate>
        </asp:UpdatePanel>

Note the button click - it now a plane jane server side event.

And our code behind now becomes this:

public partial class AjaxTest2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    

    protected void Button1_Click(object sender, EventArgs e)
    {
        txtFullName.Text = txtFirst.Text   " "   txtLast.Text;
    }

And the results are the same as the first example.

Try both. If you need a timer, then drop one of those in the update panel.

But, to be 100% clear? You can't call a non static method, since the page is still sitting on the client side in the browser - there are no non static methods you can run against the web page, since the web page is in fact NOT loaded nor avaialble at that point in time - you ONLY get to call that local routine, and it really does not nor can not know anything about the web page, and especally the "DOM" of that page - it not been posted to the server.

As noted, you can pass to the web method the values/controls on the page, have the web method do whatever, and then return a value, and then that returned value can update controls (as my first example shows).

I mean, we could say want to have a text box. You enter number of seconds, and then hit a start button. You can do this 100% client side (js) would be fine.

Or, you could again use the udpate panel.

Say, like this:

        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <h3>Enter seconds into box</h3>
                <asp:TextBox ID="txtSeconds" runat="server" ></asp:TextBox>
            <br />

                <asp:Button ID="cmdStart" runat="server" Text="Start count down" OnClick="cmdStart_Click" />

                <asp:Timer ID="Timer1" runat="server" Interval="1000" Enabled="False" OnTick="Timer1_Tick"></asp:Timer>

            </ContentTemplate>
        </asp:UpdatePanel>

So, you enter a value into the text box, and hit start. It will count down seconds from that value you entered.

Code behind will be this:

    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void cmdStart_Click(object sender, EventArgs e)
    {
        Timer1.Enabled = true;

    }
    protected void Timer1_Tick(object sender, EventArgs e)
    {
        int MySeconds = Convert.ToInt32(txtSeconds.Text);
        MySeconds -= 1;

        txtSeconds.Text = MySeconds.ToString();

        if (MySeconds <= 0)
        {
            Timer1.Enabled = false;
        }
    }
    

but again, if you doing a ajax call, there is NOT any instance of the class in existnce on the server side. It is out of scope. The server does not keep or know or have a instance of the page class in memory. After the page has been sent to the browser side, the server does NOT keep that page class in memory - hence there are no methods of the page that you can call that would be of any use - except for static methods. This is not any different then have a code module with a class in it, and you want to call use that class, but a instance of that class is NOT in existence anymore. I mean, in your code, you could create a NEW instance of the page class, but it would not have any values nor reflect the web page that is JUST sitting on their users desktop in the browser.

So, just to be clear? If you going to call a method of a class - in this case the page class, then an instance of it has to exist. Since it does not exist, then you limited to using static methods of that page class, or you live with a post-back which of course then creates a instance of that page class. this concept of a "round trip", and the page class ALWAYS going out of scope is a basic requirement and knowledge you need when writing asp.net applications.

Given your requirement to update controls on the web page, then probably a update panel is your path of least efforts. The results are "almost" as good as wiring up say ajax calls web methods, but is a boatload less work.

CodePudding user response:

I believe the error is coming from the access modifier.

The protected access modifier means that the type or member can be accessed only by code in the same class, or in a class that is derived from that class.

Try to write public instead.

  • Related