Page methods are static now
And thank god they are! As you surelly know, in previous releases they were instance methods. From a programmer's view, the great advantage that they added was that you could get the values of the controls from within the method as if you were in a "normal" postback. On the other hand, to acieve this, you'd have to send everything back to the server side, ie, you'd have to send all the form's fields back to the server side (including the hidden ones) in order to achieve the functionalities provided by those methods. This last setence should have automatically frightened you: I mean, having to send everything back in order to get a simple value is something which is show stopper for a serious AJAX application.
for a while, i thought that the methods also updated ViewState info and that they were good when you needed to perform some calculations and update the view state but didn't want to return any html to the client (don't ask me why, but i believed that till today :) ). Guess what: i was wrong. If you change the view state during an old page method call, the view state isn't returned back to the client and when you get the next partial/full postback, you'll have the same info which was there from the previous partial or full postback. So, what are the advantages of using instance page methods? I only see one: being able to get the values of the controls on the server side.
To be honest, i don't see that as an advantage since you're sending a lot of info to the server when you could just send the necessary values, Yes, you'd have to use Javascript and make a simple web service call to perform the necessary calculations, but what's that compared to sending everything back in order to get a value from the server side? It's funny, but there are a lot of guys which still believe that they can build an AJAX page without using Javascript (the last time I looked, the J standed for Javascript...maybe i'm wrong).
So, since page methods are static now, some are wondering how to achieve the same thing they did with the deprecated instance page methods. Well, the answer is simple: use the UpdatePanel control. I'm already seeing a lot of disbeliefe, but they can be used to in some scenarios in order to achieve a similar behavior. The new UpdatePanels are really cool (I never though i'd say this, but it's true: they are!). Using an UpdatePanel has several advantages over using the old page instance methods. The biggest one is that you can rely in having the view state field updated (don't forget that this field is also used for storing control state info!). there's one proble, though: the approach i'm presenting doesn't work when you need to call a client method after you're done with the processing (in those cases, just use a "normal" UpdatePanel)
The next example shows how you can do a remote page method call though an UpdatePanel without getting back the HTML normally generated by the panel. As you can see by running the sample, the panel contents aren't refreshed, but the viewstate info is correctly updated during a partial postback.
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Handle(object sender, EventArgs e)
{
ViewState["hits"] = Convert.ToInt32(ViewState["hits"]) + 1;
//maybe store something in the db here
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if( !this.IsPostBack )
{
ViewState["hits"] = 0;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" id="manager" />
<asp:UpdatePanel runat="server" ID="panel" ChildrenAsTriggers="false" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button runat="server" ID="bt" Text="simulate page method" OnClick="Handle" />
<span>Last update:</span><%= DateTime.Now.ToString( ) %>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button runat="server" ID="Button1" Text="full postback" />
<br />
<span>hit count during postback:</span><%= ViewState["hits"].ToString( ) %>
</form>
</body>
</html>
The ChildrenAsTrigger property lets you get a partial refresh without forcing the return of the UpdatePanel's HTML back to the client side.
If you don't need to call any method on the client side when the partial postback is done, then this approach does the trick. If you need to call a client method and, say, pass it a value, then you're out of luck because currently you can only insert a javascripy statement during a partial postback by using the new static RegisterXXX methods of the ScriptManager class and those statements must be associated with a control placed inside an UpdatePanel which is being refreshed during that call. This restriction makes using the UpdatePanel for calling page methods almost impossible and is one of the things i don't like about the new release.