如何从AJAX,ASP.NET WebForms调用非静态方法

发布于 2025-02-08 12:46:25 字数 690 浏览 0 评论 0原文

在模板中,我设置了每60秒设置和间隔以调用后端方法以更新响应

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

背后的代码

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

中的页面中的某些内容是服务器错误,

我尝试使用此方法使用静态方法,但也会获得实例化对象的错误来使用此信息mtheod

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花心好男孩 2025-02-15 12:46:25

当您进行Ajax调用时,它应该起作用。因此,我们必须首先修复错误。

完成此操作后,我们必须解决第二个巨大问题:

网页上的Ajax调用或Web方法是该类的“静态”成员。由于没有后后期,因此可能会发生页面控件的零更新。由于没有发生后后期,因此网页上的任何控件当然都无法修改,也无法在该Web方法背后的代码中可用。请记住,此时也无法使用ViewState(session(session()可用)。

因此,尽管AJAX调用和Web方法可以在同一网页上(和在)同一网页上,但由于没有发生后背包,因此Web方法无法修改或更改页面上的控件。

可能的解决方案:

让Ajax调用返回所需的值,然后JS代码可以更新和修改并在网页上设置控件。

或者,您可以放入ASP.NET计时器中,然后将控件(和计时器)放入更新面板的内部。这将导致我们称为部分后背包的内容,并且仅将网页(更新面板内)的部分设置为服务器,因此仅在网页上进行了更新。

当然,使用更新面板的工作要少得多,从那时起,您就不必编写任何客户端(JS)代码,并且整个过程都适合您。

好的,上述水晶在我们的脑海中清晰明了吗?

所述的Web方法可以放置在同一网页中。您不需要说例如创建单独的网页(ASCX),并将您的Web方法放入该单独的页面。但是,结果大致相同,因为如前所述,如果没有后背部,则无法更新控件,甚至可以在该网页上进行阅读/抓取/使用/查看控件,以及原因如前所述,网页仍然坐在用户桌面上。

如果您确实需要Web方法来更新页面上的某些控件,则如上所述,请使用JS客户端代码更新此类控件,或如上所述,转储AJAX调用,并介绍更新面板。结果将大致相同。 (公平地说,在有效载荷方面,Ajax调用在某种程度上“更轻”,因为更新面板确实在更新上发送了ViewState。

,让我们这样做。

因此 将两者组合到全名中的方法(我们的网络方法

我们调用一种

        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>


使用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;
    }

因此,当我们运行时,我们得到了:

”在此处输入图像描述”

因此,取决于您要在页面上更新的内容(上述AJAX调用),或者我们可以使用更新面板。

我们可以使用更新面板进行上面的操作。您也看不到和体验完整后的全页,而且工作要少得多。这确实取决于您想做的事情。

但是,请记住以上:

Web方法被认为是静态成员 - 它确实没有页面上的任何控件 - 因为没有后背包,因此您必须将Web方法标记为“”公共静态”。因此,它无法看到,获取,获取,查看或使用页面上的控件,并且对ViewState的使用也不是Avaialble。因此,该页面的任何更新都必须退回并完成客户端。

当然,另一种方法是简单地使用更新面板,我们将简单地丢弃所有3个文本框,即更新面板内部的按钮。放入脚本管理器,因此不必编写客户端JS代码。

尝试两者 - 看看您喜欢的。

那么,懒惰的骨头?

让我们使用更新面板来执行此操作。

因此,我们的标记现在为:

        <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>

注意按钮单击 - 现在是平面Jane服务器端事件。

现在,我们背后的代码成为了:

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;
    }

结果与第一个示例相同。

尝试两者。如果需要计时器,请将其中一个放在更新面板中。

但是,要100%清楚吗?
您无法调用非静态方法,因为该页面仍位于浏览器的客户端 - 没有非静态方法可以在网页上运行,因为该网页实际上未加载,也没有avaialble那个时间点 - 您只能调用该本地例程,并且它实际上也不了解该网页,尤其是该页面的“ DOM” - 它没有发布到服务器上。

如前所述,您可以传递到Web方法页面上的值/控件,让Web方法执行任何操作,然后返回值,然后返回的值可以更新控件(如我的第一个示例所示)。

我的意思是,我们可以说想要一个文本框。您输入秒数,然后点击一个开始按钮。您可以这样做100%的客户端(JS)可以。

或者,您可以再次使用紫外线面板。

这样说:

        <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>

因此,您在文本框中输入一个值,然后点击开始。它将从您输入的该值计数几秒钟。

背后的代码将是这样:

    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;
        }
    }
    

但是,如果您进行AJAX调用,则服务器端中没有任何类的实例。它超出了范围。该服务器在内存中不保留或知道或具有页面类的实例。在将页面发送到浏览器端后,服务器不会将该页面类保留在内存中 - 因此,除了静态方法外,您无法调用该页面的方法。这没有什么不同,然后有一个带有一个类的代码模块,您想调用 +使用该类,但是该类的实例不再存在。我的意思是,在您的代码中,您可以创建页面类的新实例,但是它不会有任何值,也不会反映仅坐在浏览器中的用户桌面上的网页。

所以,要清楚吗?如果要调用类的方法 - 在这种情况下,页面类,则必须存在一个实例。由于它不存在,因此您仅限于使用该页面类的静态方法,或者您与后背部生活在一起,当然,该方法当然会创建该页面的实例。在编写ASP.NET应用程序时,您需要的“往返”的概念以及页面始终超出范围的概念是您需要的基本要求和知识。

鉴于您需要在网页上更新控件,因此可能是您最少努力的更新面板。结果“几乎”与接线说Ajax调用 + Web方法一样好,但工作量更少。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文