Why do ASP.NET AJAX page methods have to be static?
AJAX, ASP.NET, OO By Dave Ward on April 16th, 2008
Dozens of variations on the title of this post are some of the most common searches that bring people here to Encosia. Unfortunately, the search engines all point to a post that doesn’t answer the question. It’s also a frequent question raised on the ASP.NET message boards, typically without a satisfactory answer provided.
However, it is an important question, the answer to which is important to understand. So, in an attempt to fill in this gap for the searchers and perhaps preemptively help others, I want to proceed to answer it as thoroughly as possible without overly complicating the whole business.
In order to do this, we’ll have to take a brief tour of WebForms, including:
- Understanding what the Page class is, and why we have it.
- One specific thing that the Page class does for us.
- How this is accomplished, behind the scenes.
- What the static keyword entails, when used with a method.
- Finally, why page methods must be static.
Note: Please bear in mind that I have taken great liberties in simplifying these concepts down to only what is necessary to answer the central question. What I will show you is conceptually accurate, but some of the implementation details are much more complex than what you will see here.
Understanding what the Page class is, and why we have it
Contorting the stateless HTTP protocol to accommodate ASP.NET’s WebForm paradigm was a considerable task for the ASP.NET team to accomplish. On top of that, going from the inline execution model of ASP classic to the event-driven model of ASP.NET also required major changes.
As such, the ubiquitous WebForms Page class was created to solve these various problems. Take this snippet, for example:
public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // Hello World. } }
I’m sure you’re familiar with the Page_Load event. The very first ASP.NET code example you were exposed to probably involved the Page_Load event. How about this portion of it though?
public partial class _Default : System.Web.UI.Page
To get you started quickly, those examples may not have explained that part very well (if at all). Later, after you get up and running, it can be easy to simply gloss over this line as cruft that comes with writing an ASP.NET page.
What this declaration means is that your code extends the Page class. Because of this, your code will include the functionality of the entire ASP.NET Page class, instead of standing on its own and requiring you to implement the mundane details.
If you’re more familiar with something like ASP classic or PHP, you can think of this Page inheritance as being functionally similar to a powerful include file that you use site-wide.
One of the Page’s most powerful features: Persistence
The Page brings a lot to the table. However, to answer the question of why page methods must be static, we need to focus on persistence.
Consider this example:
<asp:Label runat="server" id="Label1" /> <asp:Button runat="server" id="Button1" OnClick="Button1_Click" />
protected void Button1_Click(object sender, EventArgs e) { Label1.Text += DateTime.Now.ToString(); }
Each time the button is clicked, the label will have the current time and date appended to its current contents. Even this elementary example illustrates how the WebForms Page automatically provides persistence for us.
We take for granted that the Page will provide us this Label1 object after an HTTP POST from the browser. We also assume that it will automatically have a Text property with that Label’s current value.
However, this data would not normally be included in the POST data sent to the server. Only form elements are sent from the browser. The Label renders as a span element, which means that its state is not POSTed by the browser.
So, how does the Page provide us with this data anyway? Persistence.
Understanding how the Page does this
To implement this encompassing layer of persistence, the ViewState was created.
Each time a page is rendered to the browser, the Page serializes the state of its controls and then includes that information in the returned HTML, via a hidden form field named __ViewState. When a postback occurs, this hidden field can then be de-serialized to create an instance of the Page in the same state that it was at the end of the last request.
Oversimplifying, you can envision this constructor being used to re-instantiate the Page, at the beginning of every postback:
Page _Default = new Page(Request["__ViewState"]);
In our example above, the Page created through that process would look something like this after one postback:

This re-instantiation of the Page from the ViewState is what keeps the entire WebForms machine rolling, postback after postback.
What does it mean that a method is static?
A static method is simply one that is disassociated from any instance of its containing class. The more common alternative is an instance method, which is a method whose result is dependent on the state of a particular instance of the class it belongs to.
For example, both of these statements would return precisely the same string, but accomplish it through different types of methods:
// ToString() is an instance method of the DateTime class. // Its result depends on the value of each DateTime instance. return DateTime.Now.ToString(); // String.Format is a static method of the String class. // Its result is not related to any instance of the String. return String.Format("{0}", DateTime.Now);
The key difference to understand is that a static method can be called without setting up a proper instance of the class it belongs to.
In a sense, it is a stateless method.
So, why do page method calls have to be static?
If you’re implementing page methods, you’re probably well aware of their excellent performance. They are especially performant compared to the UpdatePanel’s partial postbacks.
They are efficient largely because they do not require the ViewState to be POSTed and they do not create an instance of the Page, while partial postbacks do both of these things. As we now know, a page method couldn’t create an instance of the page even if desired, since the ViewState isn’t provided in the request.
This is exactly why they must be marked as static. They cannot interact with the instance properties and methods of your Page class, because a page method call creates no instance of the Page or any of its controls.
Page methods are roughly equivalent to shorthand for standalone web services. In fact, the ScriptManager even calls them exactly as it would a regular web service.
Conclusion
While forcing the page method to be static is primarily due to technical reasons, I would suggest that it’s actually a good thing. If page methods transmitted the ViewState along with their request, in order to instantiate the Page, they would immediately lose a majority of their benefit.
Forcing the method to be static is necessary to confer most of the benefits of using page methods. Sure, it would be nice to be able to access control properties directly from within page methods, but not at the expense of transmitting volumes of extraneous data about every other control on the page.
Instead of fighting against this limitation, I say embrace efficiency.
Possibly related posts
What do you think? Your comments are welcome.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this comment" link underneath the comment you're replying to.
11 Mentions Elsewhere
- Dew Drop - April 16, 2008 | Alvin Ashcraft's Morning Dew
- rascunho » Blog Archive » links for 2008-04-16
- Interesting Finds: 2008.04.17 - gOODiDEA.NET
- Reflective Perspective - Chris Alcock » The Morning Brew #75
- Wöchentlichen Rundablage: ASP.NET MVC, Silverlight 2, WPF, WCF… | Code-Inside Blog
- Weekly Links: ASP.NET MVC, Silverlight 2, WPF, WCF… | Code-Inside Blog International
- April 28th Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Silverlight - ScottGu's Blog
- 4月28日链接篇: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Silverlight - Joycode@Ab110.com
- Eye On .NET - Hisham Elbreky
- Why Asp.net ajax page methods have to be static - Yizhe Online Tablet
- Why do ASP.NET AJAX page methods have to be static? « Talibkhan’s Weblog


Your blog is priceless! Clearly the best blog about ASP.NET AJAX!
What’s the benefit over using a web service, then? Page/UserControl methods in Anthem.NET keep track of ViewState, so I don’t see why MS Ajax can’t do it.
As far as I know, page methods have no technical benefit over web services. They are very similar.
It does seem that they put up less barrier to entry for developers who aren’t comfortable using web services though. If being able to write the page method in the page’s code-behind gets more people using them, I think that’s a win.
If you need something that keeps track of ViewState, you can always use an UpdatePanel. The Anthem.NET controls have a lot of the same drawbacks the UpdatePanels have anyway (they shuffle the entire ViewState up and down, regardless of how little of it is needed for a particular operation).
There’s no magic AJAX bullet. Either you have to bloat your requests and responses with ViewState, or you have to work within the limitations of stateless requests.
Great article, straightforward.
Keep it up!
Insightful article!. thanks.
Great article. I really enjoy the topics you choose to discuss.
One very distinct disadvantage of using PageMethods is a little-discussed phenomenon:
When debugging an ASP.NET page with PageMethods, Visual Studio will cache the result of the PageMethod. So you have to do a clean/rebuild of the solution every time you make any code changes to the PageMethod.
Interesting, I didn’t know that. Good information. Thanks for the comment.
Great article Dave! I had actually did some research on this subject myself about 2 weeks ago, never arriving at a definitive answer.
The only thing that is missing in this page methods approach is the javascript ajax-enabled UI library that you can use with page methods. You get JSON data back, yes. But you have to present it, and here we need a library to do that (including validation and error handling). I personally can’t afford to write javascript ajax-enabled UI. For example, if you use a library such as ExtJS, there is no such thing as page methods, let along asp.net ajax :)
Having said that, I honestly don’t see how these page methods can be useful if there is no UI library (all you can do is to write your own code in javascript to build UI elements, which is quite a challenge to say the least :)
In the not too distant future, I’ll probably write a post on generating the UI client side.
If you make good use of CSS for layout/styling, building the semantic structure on the fly turns out to be relatively easy.
For example, that’s how I build the table on this site. I was using an UpdatePanel to update a user control with the same content. Moving to the web service call gave me an order of magnitude performance gain (which was more than I had even expected).
Great summary. One similar question I have always had is: what are the differences between a page method and a callback method? I assume its similar to the situation in this article, but I’ve never actually found a good answer.
More or less, you can think of the callback methods as ASP.NET 2.0’s precursor to page methods. They are also still great for developing AJAX server controls, as web services and page methods aren’t very feasible for that.
Thanks Dave
really great article.
thanks again
I just discovered your blog from Scott Gu’s blog post. This was a great post, thank you. I’ve got a question about static page methods. How can you retrieve the current user’s identity from inside one? For example, let’s imagine you had a method to update someone’s phone number (they enter it in a textbox and you have a button that is just calling a javascript function, please excuse my horrible syntax)
Page.MyStaticMethod(string username, string newPhoneNumber)
I would be worried about someone just calling the javascript method manually with someone else’s username. Is there anything to prevent someone from manipulating script and changing the parameters to a page method call? If not, is there a way to just retrieve the username inside the C#? I don’t think you can access User.Identity.Name from inside the C# but I could be wrong…
I could be way off here and missing something simple… sorry if this is confusing.
You are correct that you should avoid using a method that facilitates forging on the client side. In your situation, since a page method call includes the user’s cookies in the request, identity information is available via HttpContext.Current.
For example, to get the username of a logged in user, use HttpContext.Current.User.Identity.Name in your page method.
“As we now know, a page method couldn’t create an instance of the page even if desired, since the ViewState isn’t provided in the request.
This is exactly why they must be marked as static.”
That doesn’t make any sense and is not the reason. The real question is why don’t you allow us to create non-static methods that DO post back the viewstate, so that we can access the page instance?
As I see it, we have absolutely no use for static page methods. We can already use webservices for that.
As I recall, in the early betas we did have page methods that were non static.
As far as I know, those heavyweight page methods from beta were canned due to terrible performance. If you’re willing to heft around the ViewState, you might as well just use an UpdatePanel. Passing the ViewState on a page method call defeats the entire purpose.
I’m not sure why, but I’ve found that a lot of people will write a page method, where they won’t write a web service method. I’m not sure what the friction is when it comes to writing web services, but it’s definitely there.
So, if having static page method available makes people more likely to use them, I think that’s a win for everyone.
@author:
You are wrong.
regarding “Each time a page is rendered to the browser, the Page serializes its controls (including their properties)” I can tell you the controls are NOT serialized in the Page Viewstate. Only the controls’ viewstate is put there.
Don’t trust me? Read this : http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
I think you may have missed the note that I purposely oversimplified the details of the process.
Exactly what’s serialized isn’t relevant to understanding why page methods must be static. Knowing that important state information is transmitted in the ViewState is the key.
That said, I would have to argue that serializing all of a control instances’ properties is serializing the control. Like Dave Reed says in his article:
Very good!
I use a lot this kind of method. But there is a small (or big?) detail: I cannot access the page properties, and this means that I cannot access textboxes, labels, etc (exactly as you said in your post).
So, if you have a very big form, with a lot of fields to save into the database, maybe the best way to do this is using UpdatePanel, because it submits the viewstate and, of course, the control’s values.
Another detail about the Page Methods is about the validation. It is a very useful method to validate complex data. Yeah, single data (email, phone, etc) you can validate using simple java script or the .net validators. But to complex data (if the user already exists, if this or that is true on database) the best way is using Page Method.
Ah, I had some problems when using this feature into user controls (ascx). If you see the generated HTML code, you will see that the call to the Page Method is created based on the Page name, not using the user control. So I think that we cannot use this feature into user controls, just into ASPX pages.
Again: very good post!
Bye.
I would tend to agree that for form submissions, an UpdatePanel is fine (or even a full postback).
Dave — thanks for quoting me, but still not all the properties are actually serialized, only the ones marked ‘dirty’, which typically only includes the ones that were changed dynamically.
Would it be more correct to say that the ViewState is used to serialize any non-default properties of controls that aren’t set declaratively?
I don’t want to get into an argument of semantics, when the end result is all the same in terms of understanding the topic at hand.
More correct, yes. But sometimes even default values are serialized if they are set dynamically :)
I’m not one for arguing over semantics either, but this is a topic [ViewState] that’s already widely misunderstood because it is deceptively more complex than it seems.
Fair enough. I updated that sentence of the post to be more accurate (or less inaccurate):
I certainly defer to you in any matters of the ViewState. I appreciate the feedback, Dave. Thanks!
hi , i am very impressed with ur blog.its realy priceless
Thanks alot for all info on PageMethods and especially on the efficiency of calling PageMethods with static or shared server side methods or functions.
Simple, uncomplicated and to the point, well done!
i have a user control and the ascx.vb file contains a method displaytext(), i have to call it from ascx page using PageMethods.. it’s not working.. it works fine in ASPX page.. do you have any idea??
Page methods don’t work in user controls. Most likely, you should use a web service in that situation.
is this (web service) the only way for the web service??
opps.. “web service??” should be “user control”
————-
is this (web service) the only way for the user control??
Yes, you’d need to use either an ASMX or WCF web service. You cannot define page methods in user controls.
An ASMX web service is almost identical to a page method. If you give that a try, it should come easily.
Thanks Dave
i used web service (ASMX), it’s working fine now!
Good artical Dave.Thanks.
Very good article …Thank you so much…..
Great Information Dave… Thanks Alot.
For Matt April 17th comment on static and debug.
May be this is not the place to tell but still for other’s info on Static I am writing case.
I too faced this problem.
Another problem i faced with static is
We had 2 connection string for french and eng db use to store the conn string on a static string variable depending on the page I use to change the value of variable, due to static variable the value of variable was not changing, (it was not just the case while debugging but during runtime too).
Static: I believe once static variable is used, its memory (value) is the common sharable to all the users who use this variable.
My question is if in a page on clicking a button, a label has to show from ‘A’ text to something 1,2,3… for user1,user2,user3 respectively… if user1 is using the page and get “1″ from static page method, user2 at same time will see “1″ instead of 2.
We may need to test this method with multiple users and behaviour of method simultaneously. If page method has to behave similarly everytime then it is ok. I have a doubt about static pagemethod behaviour for multiple user at same time for different results.
Oh! man.
This is a great great great post.
I read the entire article w/o taking a breath. Nicely done. A great satisfaction after reading your article. I learned from it.
Take care & Thanks.
This is a seriously awesome article. Thanks for taking the time to explain it so clearly.
Interesting article.. Anthem.NET methods don’t have to be static, that must mean that they transmit the viewstate.
Great article; thanks so much for taking the time to put this information together.
Great Article.
Saved me a lot of time..
A solution could be.. calling from the static PageMethods to external webservice project.
in this case you can use non static objects and method on the external ws.
You can also add “ip security” to the external ws.
Let me see if I got it: web methods have to be static because MS decided on a stupid implementation for server-side state serialization, right?
What I mean: of course the meanest and leanest web apps are the ones which do not keep state on the server, whether they are written in Java, ASP.Net, PHP or whatever. But there are apps which cannot be reasonably implemented without keeping state information on the server. However, ASP.Net does not provide a solution for such apps. ViewState provides a workaround, but isn’t really a solution for such apps. Why? Because if your state information is large, serialization and deserialization from ViewState is going to take a lot of time, enough so that your application is slow.
The only solution to developing fast, responsive, really web2 apps using ASP.Net is giving up server controls altogether, use a client-side only Javascript-based Ajax toolkit/framework and work with web services/web methods alone. Which of course have to be session/view state-unaware. But since MS does not provide such a toolkit integrated in ASP.Net, doing so is not quite happy coding. Until you get your toolkit of choice properly interfaced with an ASP.Net backend, it’s not really happy coding.
Web Methods do have an advantage over web services, though: they’re significantly easier and simpler to implement. However, they also have a drawback: if you don’t use them from ASP.Net, it’s not really easy to call them. But then again, JSON-based Web Services implemented using ASP.Net are also not quite straightforward to call from non-ASP.Net code.
IMO, web methods are always the better choice when you implement functionality which is not reusable. You implement web services whenever there’s a chance some other code than the one for which you write your web service will be able to make use of your web service. Whenever you need just a more or less calculation which needs to be performed server-side, but which is pertinent just to the form from which you call that code, a web service is just unnecesarily polluting the global namespace of web services exposed by an application/server/enterprise infrastructure.
Great article Dave!
Hi Dave,
I’m a little worried about the use of Static methods. In a multi-user environment (i.e. just about any web application), I thought that maybe each call to the method would be shared between all users, including any internally declared variables. To test, I created the following:
Called by:
Click here for the test.I open up two browsers, one Chrome, the other Firefox, just to make sure. In the textbox in each browser, I typed the browser name for clarity.
To my pleasant surprise, when I clicked on each “Result” div within the 5 seconds of the first click, the text updated in each respective browser/session was as hoped, namely “Chrome” in Chrome and “Firefox” in Firefox.
I’ve tested this to satisfy myself, but I was wondering if you could elaborate as to how this happens, and why the static WebMethod is not behaving like a static variable. OR, have I made a mistake in my testing, and not proved anything?
Your testing is correct. The reason you aren’t seeing a “shared” behavior across sessions is that each Page instance only exists within the scope of a single HTTP request and then is destroyed.