I've been having fun with ad-hoc AJAX calls using ASP.NET Ajax recently. And when I say fun, I mean in the sense of "no fun at all". Partly due to crap documentation and a million blog posts with example code based on obsolete beta Atlas functionality.
So here's a little tipfest about PageMethods.
You can call .NET methods of your ASPX page via client-side Javascript. But first you have to jump through some hoops:
1. The ASP.NET Ajax ScriptManager control in your .aspx or MasterPage needs to be set with: EnablePageMethods="true"
2. The .NET method you wish to expose to AJAX must be public and static and marked with the [System.Web.Services.WebMethod] attribute
Once that's done you can call your method from javascript after the AJAX script libraries have finished loading (with Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded() or something).
So, given a WebMethod like so:
[WebMethod]You call it in JavaScript with:
public static string HelloWorld()
{
return "Hello World!";
}
PageMethods.HelloWorld(MyCallbackHandler);And natch you have to provide that callback handler function e.g.
function MyCallbackHandler(Result)That's right my friends, the PageMethod takes the original argument list, plus one extra for the mandatory callback function, and then there are some optional extra callback arguments you can provide regarding error handling etc. Check out the docs for more info.
{
alert(Result);
}
One extra thing to note - I read a few blogs bitching that the WebMethod had to be declared in the .aspx page, not the code-behind code. That's not true anymore, it works fine both ways.
Zotius
ReplyDeleteexcellent blog and the code works with one exception: when I put the page into a master page file it ceases working.
Code is as follows:
The HTML Page:
%@ Page Language="C#" MasterPageFile="~/Master/MasterPage.master"AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %
asp:Content ContentPlaceHolderID="ContentPlaceHolderTop" ID="ContentHolder" runat="server"
script language="javascript" type="text/javascript"
// Javascript function
function CallSum()
{
alert("CallSum()");
//Get the controls
var txt1 = $get("txt1");
var txt2 = $get("txt2");
var txtresult = $get("txtSum");
//Call server side function
PageMethods.Sum(txt1.value,txt2.value,OnCallSumComplete,OnCallSumError,txtresult);
/*Server side function get the 2 arguments arg1 and arg2. We are passing txt1.value and txt2.value
for that. OnCallSumComplete is callback function for complete successfully. OnCallSumError is callback
function on error. txtresult is usercontext parameter.
OnCallSumComplete,OnCallSumError,txtresult are optional parameters.
If server side code executed successfully then OnCallSumComplete will call.
If server side code do not executed successfully then OnCallSumError will call.
*/
alert("CallSum2");
}
// Callback function on complete
// First argument is always "result" if server side code returns void then this value will be null
// Second argument is usercontext control pass at the time of call
// Third argument is methodName (server side function name) In this example the methodName will be "Sum"
function OnCallSumComplete(result,txtresult,methodName)
{
alert("OnCallSumComplete()");
//Show the result in txtresult
txtresult.value = result;
}
// Callback function on error
// Callback function on complete
// First argument is always "error" if server side code throws any exception
// Second argument is usercontext control pass at the time of call
// Third argument is methodName (server side function name) In this example the methodName will be "Sum"
function OnCallSumError(error,userContext,methodName)
{
alert("OnCallSumError");
if(error !== null)
{
alert(error.get_message());
}
}
// -->
/script
body
div
table
tr
td
Number1:/td
td
asp:TextBox ID="txt1" runat="server" /asp:TextBox
/td
/tr
tr
td
Number2:/td
td
asp:TextBox ID="txt2" runat="server" /asp:TextBox
/td
/tr
tr
td
Sum:/td
td
asp:TextBox ID="txtSum" runat="server" /asp:TextBox
/td
/tr
tr
td
asp:Button ID="btnSum" runat="server" Text="Sum" OnClientClick="CallSum();return false;" /
/td
/tr
/table
/div
/body
/asp:Content
my code behind:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Page.Title = "test";
}
}
/// summary
/// Server side function Sum
/// /summary
/// param name="arg1" arg1 /param
/// param name="arg2" arg2 /param
/// returns result(sum)/returns
[System.Web.Services.WebMethod]
public static int Sum(int arg1, int arg2)
{
/* On server side we can do any thing. Like we can access the Session.
* We can do database access operation. Without postback.
*/
try
{
return arg1 + arg2;
}
catch(Exception ex)
{
throw ex;
}
}
}
Why does it not work?
(Ihave had to strip out angle brackets for the post to be allowed)
Adrian (In Harrogate)
Interesting, I'll check it out at work in the morning. It ought to work cos my current project uses MasterPages and the PageMethods seem to work fine.
ReplyDeleteOne avenue to consider is your browser's caching of the javascript files that ASP.NET AJAX creates for the PageMethod stubs. Think that caught me out at one point.
how to pass argument to on success function from javascript function ?
ReplyDeleteHow to not get question answered ?
ReplyDeleteBesides, I'd do this in jQuery these days, like so: http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/