0

I call a method in a separate Class file that needs to update a label.

    [WebMethod] //needed for the AJAX call
    public static void MyClick(int postid, int userid) //must be static
    {
        Page page = new Page();
        //Page page = HttpContext.Current.Handler as Page //Pass the Page but don't work
        MyClass.MyMethod(postid, userid, page);
    }

The method MyClick() is called from an asp.aspx file (With MasterPage), to a separate MyClass.cs file.

I am not being able to get the Control (Label) with FindControl(). My guess is the "Page" is not being passed correctly. For what i've seen in debug, "page" comes with many exceptions.

((Label)page.FindControl("ContentPlaceHolder1_lbl)).Text = "foo";  

This is the sequence:
1) User clicks sort of a "Like" dynamically-created LinkButton
2) There is a JS listener that on click changes to "Dislike" (example) and does an AJAX POST to aspx page method MyClick() with parameters (postid, userid).
3) MyClick() calls MyMethod(postid, userid) that is in MyClass.cs
4) MyMethod() does some SQL (was working) and updates the label (AJAX call not working since MyMethod() tries to set label to "foo").

Dillinger
  • 341
  • 3
  • 16

1 Answers1

2

You're not passing the current page, you're creating a new one:

Page page = new Page();

You could just pass a reference to the current page:

MyClass.MyMethod(postid, userid, this);

(Though in order to do that your page method shouldn't be static. In fact, in order to reference anything on the page instance that method shouldn't be static. See edit below)

However, in general it's best practice not to have other components rely on your page elements. Only the page's code should know/care about the UI elements it owns.

Instead of having the method set the value, have the method compute and return the value and then have the page set it. Something like this:

var result = MyClass.MyMethod(postid, userid);
myLabel.Text = result;

That way the external component isn't tightly coupled to this specific page, can be re-used by other pages, etc.


Edit: What you're trying to do physically won't work in the framework you're using. AJAX-invoked web methods are static for a reason. They don't maintain page state. So in the context of that web method there is no page and there is no label. The AJAX call is a simple service which accepts values and returns a response.

So even if you could update a label server-side, that's not going to do anything client-side. Your client-side code needs to update the markup in the browser. To do that, the AJAX call should simply respond with the new value and the JavaScript code should use that returned value to update the page. Something like this:

[WebMethod]
public static string MyClick(int postid, int userid)
{
    return MyClass.MyMethod(postid, userid);
}

As in the earlier part of this answer, that external component should simply calculate and respond with the new value. It should not be coupled to the page. This web method should result in the client-side code receiving the updated value. Then, however you manage that client-side (you have no client-side code in the question), you would update the page markup with that resulting value.

David
  • 208,112
  • 36
  • 198
  • 279
  • I can't use "this" because the MyMethod() is static (must be because is a [WebMethod]). I understand your logic, but in this case i would like to pass the page to MyMethod(), because MyClick() is called in an AJAX call. – Dillinger Aug 03 '15 at 15:03
  • @Dillinger: The fact that you're using AJAX has no bearing on what I'm suggesting. Non-page components shouldn't be tightly coupled to page components. Also, why does this method have to be `static`? As you say, a static member has no reference to any instance members. So you can't reference the page *or* the label (or any other control on the page). It sounds like this really should be an instance method. `MyClass.MyMethod()` can be `static`, but the page's method shouldn't be. – David Aug 03 '15 at 15:07
  • @Dillinger: I'm also very much questioning whether or not setting the `label` will actually *do anything* in an AJAX call. It's possible that I'm simply not familiar with some framework magic going on behind the scenes, but unless something is actually *applying* that change to the client-side markup then what you're doing simply isn't going to work anyway. – David Aug 03 '15 at 15:14
  • as soon as i remove the "static"; the MyClick() (which is a [WebMethod]) stops working. – Dillinger Aug 03 '15 at 15:18
  • @Dillinger: I guess AJAX-based web methods *do* need to be `static`? (I just did some Googling on the subject.) That seems to make sense from a performance perspective, there's no need to maintain page state for a simple one-off service. But what that means is exactly that... There is no page state to reference. So in the context of your AJAX call there *is no* page, and there *is no* label. What you're trying to do (update a label server-side without page state) simply won't work. Your AJAX call needs to return the value and *client-side* code needs to update the page. – David Aug 03 '15 at 15:25
  • I've added some information to my original post. I appreciate some workaround from this. Meanwhile i'll post the solution when i find it. Thanks David. – Dillinger Aug 03 '15 at 15:38