In order to begin utilizing PageMethods in your ASP.Net AJAX enabled webpage, you need to do 3 things:
- Set the ScriptManager's "EnablePageMethods" property to "true".
- Write Public Static WebMethods in the Code Behind file of the web page that will return the information required.
- Write JavaScript that calls the PageMethods and reacts to the return results (information or errors).
Setting up the Script Manager
Setting up the ScriptManager to handle PageMethods is fairly straightforward; however, there's one thing that you'll need to be aware of. The "EnablePageMethods" property is only found on the ScriptManager control and not the ScriptManagerProxy control. This means that if you have a Master Page with a ScriptManager control in it used by the Content Page that will contain the PageMethods, you must set the Master Page's ScriptManger control to include the property. Doing such enables all pages that use that master page to be able to use PageMethods. I haven't investigated to see the impact this has on pages that do not utilize PageMethods.With that out of the way, in order to enable page methods on a page, simply go to your ScriptManager control that's associated with the page and set the "EnablePageMethods" property to "True". This is "False" by default, but once you set it to "True" you're all set.
Writing the Server Code
Now that we can write PageMethods, we need to flip to our code behind files (or our <script runat=server> sections) to begin. Below are the steps that I traditionally follow when creating PageMethods:- Create a new method/function that returns String or value type (Integers, Doubles, Dates, etc.).
- Mark the new method as Public Static (or Shared for the VB coders out there)
- Import the System.Web.Services namespace
- Add the [WebMethod()] (or <WebMethod()>) Attribute to the Function
[WebMethod()]
public static string MyPageMethod(string someParam)
{
return "Hello, PageMethods!";
}
When the page loads, the ScriptManager will examine the page's definition for any public static webmethods. It will then generate JavaScript code that is used to call these methods and append it into the ASP.Net AJAX's PageMethods object. This interaction allows our new method to be called from JavaScript by referencing in JavaScript the method of the same name of the PageMethods object ( PageMethods.MyPageMethod(...) in this case - more on this below).
Making the calls with JavaScript
So far we have enabled PageMethods in our ScriptManager and have made some static web methods in our code that the ScriptManager will create JavaScript from. Now, we need to write our own JavaScript code to call these PageMethods so that we can retrieve the information they provide.
In order to create the JavaScript code to call the PageMethods, you simply have to make have 3 things:
- The script that calls the PageMethod itself
- A function to call on each successful PageMethod call
- A function to call when ever there was an error in the PageMethod call.
The code to call the PageMethod is very simple.
function callerMethod() {
PageMethods.MyPageMethod(PARAM1,
PARAM2,
PARAMn,
callerMethod_Success,
callerMethod_Failure);
}
Let's pick this apart now. What we have above is a simple JavaScript function called "callerMethod". Inside of this function, we do a simple call to our method's JavaScript counterpart that got attached to the PageMethods JavaScript object that's included by the ScriptManager. Next, we pass any parameters required (signified by the "PARAM1", "PARAM2", and "PARAMn" in this case) followed by a pointer/name of the method to call on a successful transmission and the same for the failed transmission.
One optional parameter that I've purposefully excluded can appear at the very end is designated for the current UserContext. In a later posting, I will provide more information revolving around this parameter and how to use it to provide more powerful communication models in the code. For right now, we will exclude the parameter because we can.
Now that we've created the call, we need to create the functions that'll be called when the transmission succeeds or fails.
function callMethod_Success(results, userContext, methodName) {
alert(results);
}
function callMethod_Failure(errors, userContext, methodName) {
alert(errors.get_Message());
}
Again, these are very simple methods that do nothing other than alerting the user of the resulting value on success or the error messsage on failure. The names of the methods are completely up to you naturally; however, whatever you name the methods, each require 3 parameters.
The first parameter of is for the returned value or error that the call to the PageMethod created. On success, you can immediately begin using the results as if they were a normal value passed into any regular function (since it's either a String or Number JavaScript type). On failure, the PageMethod and ScriptManage return an object with information about the error. The get_Message() method of the error object will return the error message that was thrown during the transmission. Once you have the resulting value (success or failure), you can then write JavaScript logic to do whatever you want with it.
The second parameter is the userContext. Like previously stated, this will be covered in a future posting. For now, just remember that you can send the userContext to the PageMethod and read the resulting context on the returning trip.
The last parameter of the success and failure methods is the methodName. This parameter provides a simple string that represents the PageMethod name that was called and caused the success or failure function to be triggered. This is a great addition to the returning functions since it allows you to reuse success and/or failure functions across different PageMethods and produce custom logic based on which PageMethod was called. While I can see some merit in having a single success and a single failure (or even 1 function that does both), I wouldnt' want to maintain the if statements that would spawn from such logic.
Summary
While the example code here isn't too useful (like most Hello, World projects), it hopefully will get you started on using PageMethods. In future postings, I'll provide some addition information and techniques that you can use in order to utilize PageMethods by using the UserContext object, identifying more in depth the data types that can and cannot be passed, and also object serialization through JSON. In addition to these items, I'll also be keeping an eye out on any items that may be not quite so obvious when you're work with PageMethods. Down the road a bit, I'll do a very similar post to this about using local WebServices instead of PageMethods and why.