Search code examples
c#asp.netcode-behindstatic-methodsobject-reference

How to call non-static method from static method in an aspx.cs code-behind


A similar question was asked elsewhere, but the answer doesn't seem to work in my particular situation.
I have a hidden field on an aspx page:

<asp:HiddenField ID="dataReceiver" runat="server" Value="" />

I'm trying to access this field from the codebehind. It seems like I have to reference it from within the default class that's automatically generated by VS2010. Since I can't create a new class I tried the following.

1public partial class _Default : System.Web.UI.Page
2{
3   protected void Page_Load(object sender, EventArgs e)
4   {
5       Data2();
6       MessageBox.Show(dataReceiver.Value);
7   }

8   public void Data1()
9   {
10      dataReceiver.Value = "123456";
11  }

12  public static void Data2()
13  {
14      _Default def = new _Default();
15      def.Data1();
16  }
17}

This generates an error at Line 10: "Object reference not set to an instance of an object."

I've also tried typing Line 14 as "_Default def = new _Default().Data1();" but this is rejected by the compiler with an error: "Cannot implicitly convert type 'void' to 'WebApplication6._Default'"

Is there a way to make this work, or do I need a completely different approach?

[EDIT] Darin's response below resolved this for me, but it did take me a little while to figure out how to apply the information. I thought I should clarify the details of the solution in case anyone reads this later with a similar problem.
Although the WebMethod can't call an instance method, and it doesn't seem to be able to access elements of the page regardless of their "runat" attribute, it can return a value to the JavaScript method calling it. The value will be accessible in the JavaScript as a local variable called "result" which is passed to the "success" or "failure" functions.

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager id="scriptManager1" runat="server" EnablePageMethods= "true" />
<asp:HiddenField ID="dataReceiver" runat="server" Value="789" />
</asp:Content>
//Javascript
function callServer() {
    PageMethods.Data2($("#MainContent_dataReceiver").attr("value").toString(), success, failure);

    function success(result, userContext, methodName) { alert(result + " . " + userContext + " . " + methodName); }
    function failure(result, userContext, methodName) { alert(result + " . " + userContext + " . " + methodName); }
}
//C# Code Behind
[WebMethod]
public static string Data2(string value)
{
    value = "101112";
    return value;
}

Solution

  • You cannot access instance fields from a PageMethod in ASP.NET which I suspect is what you are trying to achieve here. That's how it is and there's not much you could do about it. So what I would recommend you is to simply have your page method take the value of the hidden field as argument:

    public static void Data2(string value)
    {
        ... do something with the value of the hidden field
    }
    

    Now let the caller of the page method supply the required value since it is in the context of the page.