When it comes to lightweight client-side communication, I’ve noticed that many of you prefer ASP.NET AJAX’s page methods to full ASMX web services. In fact, page methods came up in the very first comment on my article about using jQuery to consume ASMX web services.
Given their popularity, I’d like to give them their due attention. As a result of Justin’s question in those comments, I discovered that you can call page methods via jQuery. In fact, it turns out that you can even do it without involving the ScriptManager at all.
In this post, I will clarify exactly what is and isn’t necessary in order to use page methods. Then, I’ll show you how to use jQuery to call a page method without using the ScriptManager.
Creating a page method for testing purposes.
Writing a page method is easy. They must be declared as static, and they must be decorated with the [WebMethod] attribute. Beyond that, ASP.NET AJAX takes care of the rest on the server side.
This will be our page method for the example:
public partial class _Default : Page
{
[WebMethod]
public static string GetDate()
{
return DateTime.Now.ToString();
}
}
What about the ScriptManager and EnablePageMethods?
Traditionally, one of your first steps when utilizing page methods is to set the ScriptManager’s EnablePageMethods property to true.
Luckily, that property is a bit of a misnomer. It doesn’t enable page methods at all, but simply generates an inline JavaScript proxy for all of the appropriate methods in your page’s code-behind.
For example, if a ScriptManager is added to the above example’s corresponding Default.aspx and its EnablePageMethods property is set to true, this JavaScript will be injected into the page:
var PageMethods = function() {
PageMethods.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
PageMethods.prototype = {
_get_path:function() {
var p = this.get_path();
if (p) return p;
else return PageMethods._staticInstance.get_path();},
GetDate:function(succeededCallback, failedCallback, userContext) {
return this._invoke(this._get_path(), 'GetDate',false,{},
succeededCallback,failedCallback,userContext); }}
PageMethods.registerClass('PageMethods',Sys.Net.WebServiceProxy);
PageMethods._staticInstance = new PageMethods();
// Generic initialization code omitted for brevity.
PageMethods.set_path("/jQuery-Page-Method/Default.aspx");
PageMethods.GetDate = function(onSuccess,onFailed,userContext) {
PageMethods._staticInstance.GetDate(onSuccess,onFailed,userContext);
}
Don’t worry if you don’t understand this code. You don’t need to understand how it works. Just understand that this JavaScript proxy is what allows you to call page methods via the PageMethods.MethodName syntax.
The important takeaway here is that the PageMethods proxy object boils down to a fancy wrapper for a regular ASP.NET service call.
Calling the page method with jQuery instead.
Knowing that a page method is consumed in the same way as a web service, consuming it with jQuery isn’t difficult. For more detailed information, see my previous article about making jQuery work with ASP.NET AJAX’s JSON serialized web services.
Using the jQuery.ajax method, this is all there is to it:
$.ajax({
type: "POST",
url: "PageName.aspx/MethodName",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Do something interesting here.
}
});
Putting it all together.
Corresponding to the example page method above, here’s our Default.aspx:
As you can see, there’s no ScriptManager required, much less EnablePageMethods.
As referenced in Default.aspx, this is Default.js:
$(document).ready(function() {
// Add the page method call as an onclick handler for the div.
$("#Result").click(function() {
$.ajax({
type: "POST",
url: "Default.aspx/GetDate",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Replace the div's content with the page method's return.
$("#Result").text(msg.d);
}
});
});
});
The end result is that when our result div is clicked, jQuery makes an AJAX call to the GetDate page method and replaces the div’s text with its result.
If you’re wondering about the msg.d, be sure to see my post about what it is, why it’s there, and why you may not need it in your version of ASP.NET: A breaking change between versions of ASP.NET AJAX
Conclusion
Page methods are much more openly accessible than it may seem at first. The relative unimportance of EnablePageMethods is a nice surprise.
To demonstrate the mechanism with minimal complications, this example has purposely been a minimal one. If you’d like to see a real-world example, take a look at Moses’ great example of using this technique to implement a master-detail drill down in a GridView.
If you’re already using the ScriptManager for other purposes, there’s no harm in using its JavaScript proxy to call your page methods. However, if you aren’t using a ScriptManager or have already included jQuery on your page, I think it makes sense to use the more efficient jQuery method.
Monday, May 18, 2009
API 1.3 Ajax
Ajax Requests:
Name & Type
jQuery.ajax( options ) : Returns: XMLHttpRequest
Load a remote page using an HTTP request.
load( url, data, callback ) : Returns: jQuery
Load HTML from a remote file and inject it into the DOM.
jQuery.get( url, data, callback, type ) : Returns: XMLHttpRequest
Load a remote page using an HTTP GET request.
jQuery.getJSON( url, data, callback ) : Returns: XMLHttpRequest
Load JSON data using an HTTP GET request.
jQuery.getScript( url, callback ) : Returns: XMLHttpRequest
Loads, and executes, a local JavaScript file using an HTTP GET request.
jQuery.post( url, data, callback, type ) : Returns: XMLHttpRequest
Load a remote page using an HTTP POST request.
Ajax Events:
Name & Type
ajaxComplete( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request completes. This is an Ajax Event.
ajaxError( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request fails. This is an Ajax Event.
ajaxSend( callback ) Returns: jQuery
Attach a function to be executed before an AJAX request is sent. This is an Ajax Event.
ajaxStart( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request begins and there is none already active. This is an Ajax Event.
ajaxStop( callback ) Returns: jQuery
Attach a function to be executed whenever all AJAX requests have ended. This is an Ajax Event.
ajaxSuccess( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request completes successfully. This is an Ajax Event.
Misc:
Name & Type
jQuery.ajaxSetup( options )
Setup global settings for AJAX requests.
serialize( ) Returns: String
Serializes a set of input elements into a string of data.
serializeArray( ) Returns: Array
Name & Type
jQuery.ajax( options ) : Returns: XMLHttpRequest
Load a remote page using an HTTP request.
load( url, data, callback ) : Returns: jQuery
Load HTML from a remote file and inject it into the DOM.
jQuery.get( url, data, callback, type ) : Returns: XMLHttpRequest
Load a remote page using an HTTP GET request.
jQuery.getJSON( url, data, callback ) : Returns: XMLHttpRequest
Load JSON data using an HTTP GET request.
jQuery.getScript( url, callback ) : Returns: XMLHttpRequest
Loads, and executes, a local JavaScript file using an HTTP GET request.
jQuery.post( url, data, callback, type ) : Returns: XMLHttpRequest
Load a remote page using an HTTP POST request.
Ajax Events:
Name & Type
ajaxComplete( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request completes. This is an Ajax Event.
ajaxError( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request fails. This is an Ajax Event.
ajaxSend( callback ) Returns: jQuery
Attach a function to be executed before an AJAX request is sent. This is an Ajax Event.
ajaxStart( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request begins and there is none already active. This is an Ajax Event.
ajaxStop( callback ) Returns: jQuery
Attach a function to be executed whenever all AJAX requests have ended. This is an Ajax Event.
ajaxSuccess( callback ) Returns: jQuery
Attach a function to be executed whenever an AJAX request completes successfully. This is an Ajax Event.
Misc:
Name & Type
jQuery.ajaxSetup( options )
Setup global settings for AJAX requests.
serialize( ) Returns: String
Serializes a set of input elements into a string of data.
serializeArray( ) Returns: Array
Tuesday, May 12, 2009
Ajax Overview
Web technological terms
HTML
The World Wide Web is constructed from many millions of individual pages,
and those pages are written in a language called HTML. The purpose
of this language is to display the content in the browser.
Cascading Style Sheets
Normal files with HTML understandable style syntax that results colorful
display of the content in the browser.
JavaScript
Scripting code that is embedded in the HTML to make the normal HTML
pages more dynamic.
Server script
Script at the server side that provides results to the clients requests.
EX: PHP,ASP,JSP,ASP.NET
Framework
A Framework in software development is defined as the support structure in
which other projects can be developed and organized.
Library
A library is defined as a collection of related functions and subroutines used
to develop software. They are not independent programs.
Toolkits
A toolkit is generally used in reference to graphical user interface (GUI)
toolkits. Basically, a library that is mainly focused on creating a GUI..
Object
Ajax allows you to add to your web application interfaces some of this
functionality more commonly seen in desktop applications and often
referred to as a rich user experience.
To achieve this, Ajax builds an extra layer of processing between the
web page and the server. This layer is commonly referred as
AJAX Engine (or)
AJAX Framework
The updating of page elements to reflect the revised information received
from the server is also looked after by Ajax, happening dynamically
while the page continues to be used.
An object can be thought of a single package contains set of properties,which
contains and classify the data,set of methods with which objects can perform
actions on the data.
Constituent stages in AJAX
XMLHTTPRequest Object
Heart of the AJAX Engine and it is responsible to carry the HTTP request
to the server asynchronously.
Note The XMLHTTPRequest object can generally only make calls to URLs within the same domain as the
calling page and cannot directly call a remote server.
Talking with the Server
XMLHTTPRequest talks with the server with its appropriate methods and
properties asynchronously at the backside.
Server Response
As per the Server script is concerned the request from the
XMLHTTPRequest is just another HTTP request.
Dealing with the Server Response
Once after the AJAX Engine gets notified about the sucessful execution.
It modifies the data according to the functionality and keeps in place.
AJAX Engine setup
XMLHTTPRequest Object Properties and Methods
onreadystatechange Determines which event handler will be called when
the object's readyState property changes
readystate
Integer reporting the status of the request:
0 = uninitialized
1 = loading
2 = loaded
3 = interactive
4 = completed
responseText Data returned by the server in text string form
responseXML Data returned by the server expressed as the document
object
status HTTP status code returned by server
statusText HTTP reason phrase returned by server
Methods Description
abort() : Stops the current request
GetAllResponseHeaders() : Returns all headers as a string
getresponseHeader(x) : Returns the value of header x as a string
open('method','URL','a') : specifies the HTTP method (for example, GET or POST),
the target URL, and whether the request should be
handled asynchronously (If yes, a='True'the default;
if no, a='false'.)
send(content) : HTTP status code returned by server
setRequestHeader('x','y') : HTTP reason phrase returned by server
send() Method
Once the XMLHTTPRequest object is prepared with the open() method, it is
possible to send the request with the send() method.
If the request uses GET method ,then we can use send with a single
argument null
objectInstance.send(null);
If the request uses POST method ,we must feed the content type and the
values.
objectInstance.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
objectInstance.send(var1=value1&var2=value2);
Creating the XMLHTTPRequest Object with Cross Browser solution
We can provide the solution for the Cross-Browsers using two ways
1. Using Object Detection
function getXMLHTTPRequest()
{
var request = false;
try
{
request = new XMLHttpRequest(); /* e.g. Firefox */
}
catch(err1)
{
try
{
vrequest = new ActiveXObject("Msxml2.XMLHTTP"); /* some versions IE */
}
catch(err2)
{
try
{
request = new ActiveXObject("Microsoft.XMLHTTP"); /* some versions IE */
}
catch(err3)
{
request = false;
}
}
}
return request;
}
2. Using Browser Detection
function getXMLHTTPRequest()
{
var request = false;
if(window.XMLHTTPRequest)
{
request = new XMLHTTPRequest();
} else {
if(window.ActiveXObject)
{
try
{
request = new ActiveXObject("Msml2.XMLHTTP");
}
catch(err1)
{
try
{
request = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(err2)
{
request = false;
}
}
}
}
return request;
}
HTML
The World Wide Web is constructed from many millions of individual pages,
and those pages are written in a language called HTML. The purpose
of this language is to display the content in the browser.
Cascading Style Sheets
Normal files with HTML understandable style syntax that results colorful
display of the content in the browser.
JavaScript
Scripting code that is embedded in the HTML to make the normal HTML
pages more dynamic.
Server script
Script at the server side that provides results to the clients requests.
EX: PHP,ASP,JSP,ASP.NET
Framework
A Framework in software development is defined as the support structure in
which other projects can be developed and organized.
Library
A library is defined as a collection of related functions and subroutines used
to develop software. They are not independent programs.
Toolkits
A toolkit is generally used in reference to graphical user interface (GUI)
toolkits. Basically, a library that is mainly focused on creating a GUI..
Object
Ajax allows you to add to your web application interfaces some of this
functionality more commonly seen in desktop applications and often
referred to as a rich user experience.
To achieve this, Ajax builds an extra layer of processing between the
web page and the server. This layer is commonly referred as
AJAX Engine (or)
AJAX Framework
The updating of page elements to reflect the revised information received
from the server is also looked after by Ajax, happening dynamically
while the page continues to be used.
An object can be thought of a single package contains set of properties,which
contains and classify the data,set of methods with which objects can perform
actions on the data.
Constituent stages in AJAX
XMLHTTPRequest Object
Heart of the AJAX Engine and it is responsible to carry the HTTP request
to the server asynchronously.
Note The XMLHTTPRequest object can generally only make calls to URLs within the same domain as the
calling page and cannot directly call a remote server.
Talking with the Server
XMLHTTPRequest talks with the server with its appropriate methods and
properties asynchronously at the backside.
Server Response
As per the Server script is concerned the request from the
XMLHTTPRequest is just another HTTP request.
Dealing with the Server Response
Once after the AJAX Engine gets notified about the sucessful execution.
It modifies the data according to the functionality and keeps in place.
AJAX Engine setup
XMLHTTPRequest Object Properties and Methods
onreadystatechange Determines which event handler will be called when
the object's readyState property changes
readystate
Integer reporting the status of the request:
0 = uninitialized
1 = loading
2 = loaded
3 = interactive
4 = completed
responseText Data returned by the server in text string form
responseXML Data returned by the server expressed as the document
object
status HTTP status code returned by server
statusText HTTP reason phrase returned by server
Methods Description
abort() : Stops the current request
GetAllResponseHeaders() : Returns all headers as a string
getresponseHeader(x) : Returns the value of header x as a string
open('method','URL','a') : specifies the HTTP method (for example, GET or POST),
the target URL, and whether the request should be
handled asynchronously (If yes, a='True'the default;
if no, a='false'.)
send(content) : HTTP status code returned by server
setRequestHeader('x','y') : HTTP reason phrase returned by server
send() Method
Once the XMLHTTPRequest object is prepared with the open() method, it is
possible to send the request with the send() method.
If the request uses GET method ,then we can use send with a single
argument null
objectInstance.send(null);
If the request uses POST method ,we must feed the content type and the
values.
objectInstance.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
objectInstance.send(var1=value1&var2=value2);
Creating the XMLHTTPRequest Object with Cross Browser solution
We can provide the solution for the Cross-Browsers using two ways
1. Using Object Detection
function getXMLHTTPRequest()
{
var request = false;
try
{
request = new XMLHttpRequest(); /* e.g. Firefox */
}
catch(err1)
{
try
{
vrequest = new ActiveXObject("Msxml2.XMLHTTP"); /* some versions IE */
}
catch(err2)
{
try
{
request = new ActiveXObject("Microsoft.XMLHTTP"); /* some versions IE */
}
catch(err3)
{
request = false;
}
}
}
return request;
}
2. Using Browser Detection
function getXMLHTTPRequest()
{
var request = false;
if(window.XMLHTTPRequest)
{
request = new XMLHTTPRequest();
} else {
if(window.ActiveXObject)
{
try
{
request = new ActiveXObject("Msml2.XMLHTTP");
}
catch(err1)
{
try
{
request = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(err2)
{
request = false;
}
}
}
}
return request;
}
Monday, May 11, 2009
Black boxes vs. White boxes Ajax
When most people use a microwave oven, they have no idea how it
actually works. They only know that if they put food in and turn the oven
on, the food will get hot in a few minutes. By contrast, a toaster is fairly
easy to understand. When you’re using a toaster, you can just look inside
the slots to see the elements getting hot and toasting the bread.
A traditional Web application is like a microwave oven. Most users
don’t know how Web applications work and don’t even care to know how
they work. Furthermore, most users have no way to find out how a given
application works even if they did care. Beyond the fundamentals, such
as use of HTTP as a request protocol, there is no guaranteed way to
determine the inner workings of a Web site. By contrast, an Ajax Web
application is more like a toaster. While the average user may not be
aware that the logic of the Ajax application is more exposed than that of
the standard Web page, it is a simple matter for an advanced user (or an
attacker) to “look inside the toaster slots” and gain knowledge about the
internal workings of the application.
Black boxes vs. White boxes
Web applications (and microwave ovens) are examples of “black box”
systems. From the user’s perspective, input goes into the system, and
then output comes out of the system. The application logic that processes
the input and returns the output is abstracted from the user and is
invisible to him.
The inner workings of a black box system are unknown to the user
For example, consider a weather forecast Web site. A user enters his
ZIP code into the application, and the application then tells him if the
forecast calls for rain or sun. But how did the application gather that data?
It may be that the application performs real-time analysis of current
weather radar readings, or it may be that every morning a programmer
watches the local television forecast and copies that into the system.
Since the end user does not have access to the source code of the
application, there is really no way for him to know.
Security Note
There are in fact some situations in which an end user
may be able to obtain the application’s source code.
These situations mostly arise from improper
configuration of the Web server or insecure source code
control techniques, such as storing backup files on
production systems. Please review Chapter 3 for more
information on these types of vulnerabilities.
“White box” systems behave in the opposite manner. Input goes into
the system and output comes out of the system as before, but in this case
the internal mechanisms (in the form of source code) are visible to the
user.
The user can see the inner workings of a white box system
Any interpreted script-based application, such as a batch file, macro,
or (more to the point) a JavaScript application, can be considered a white
box system. As we discussed in the previous chapter, JavaScript must be
sent from the server to the client in its original, unencrypted source code
form. It is a simple matter for a user to open this source code and see
exactly what the application is doing.
It is true that Ajax applications are not completely white box systems since there is still a
large portion of the application that executes on the server. However, they are much
more transparent than traditional Web applications, and this transparency provides
opportunities for hackers, as we will demonstrate over the course of the chapter.
It is possible to obfuscate JavaScript, but this is different than
encryption. Encrypted code is impossible to read until the correct key is
used to decrypt it, at which point it is readable by anyone. Encrypted code
cannot be executed until it is decrypted. On the other hand, obfuscated
code is still executable as-is. All the obfuscation process accomplishes is
to make the code more difficult to read by a human. The key phrases
here are that obfuscation makes code “more difficult” for a human to read,
while encryption makes it “impossible”, or at least virtually impossible.
Someone with enough time and patience could still reverse-engineer the
obfuscated code. As we saw in Chapter 2, Eve created a program to deobfuscate
JavaScript. In actuality, the authors created this tool, and it only
took a few days. For this reason, obfuscation should be considered more
of a speed bump than a roadblock for a hacker: it may slow a determined
attacker down but it will not stop him.
In general, white box systems are easier to attack than black box
systems because their source code is more transparent. Remember that
attackers thrive on information. A large percentage of the time that a
hacker spends attacking a Web site is not actually spent sending
malicious requests, but rather analyzing it to determine how it works. If
the application freely provides details of its implementation, this task is
greatly simplified. Let’s continue the weather forecasting Web site
example and evaluate it from an application logic transparency point of
view.
actually works. They only know that if they put food in and turn the oven
on, the food will get hot in a few minutes. By contrast, a toaster is fairly
easy to understand. When you’re using a toaster, you can just look inside
the slots to see the elements getting hot and toasting the bread.
A traditional Web application is like a microwave oven. Most users
don’t know how Web applications work and don’t even care to know how
they work. Furthermore, most users have no way to find out how a given
application works even if they did care. Beyond the fundamentals, such
as use of HTTP as a request protocol, there is no guaranteed way to
determine the inner workings of a Web site. By contrast, an Ajax Web
application is more like a toaster. While the average user may not be
aware that the logic of the Ajax application is more exposed than that of
the standard Web page, it is a simple matter for an advanced user (or an
attacker) to “look inside the toaster slots” and gain knowledge about the
internal workings of the application.
Black boxes vs. White boxes
Web applications (and microwave ovens) are examples of “black box”
systems. From the user’s perspective, input goes into the system, and
then output comes out of the system. The application logic that processes
the input and returns the output is abstracted from the user and is
invisible to him.
The inner workings of a black box system are unknown to the user
For example, consider a weather forecast Web site. A user enters his
ZIP code into the application, and the application then tells him if the
forecast calls for rain or sun. But how did the application gather that data?
It may be that the application performs real-time analysis of current
weather radar readings, or it may be that every morning a programmer
watches the local television forecast and copies that into the system.
Since the end user does not have access to the source code of the
application, there is really no way for him to know.
Security Note
There are in fact some situations in which an end user
may be able to obtain the application’s source code.
These situations mostly arise from improper
configuration of the Web server or insecure source code
control techniques, such as storing backup files on
production systems. Please review Chapter 3 for more
information on these types of vulnerabilities.
“White box” systems behave in the opposite manner. Input goes into
the system and output comes out of the system as before, but in this case
the internal mechanisms (in the form of source code) are visible to the
user.
The user can see the inner workings of a white box system
Any interpreted script-based application, such as a batch file, macro,
or (more to the point) a JavaScript application, can be considered a white
box system. As we discussed in the previous chapter, JavaScript must be
sent from the server to the client in its original, unencrypted source code
form. It is a simple matter for a user to open this source code and see
exactly what the application is doing.
It is true that Ajax applications are not completely white box systems since there is still a
large portion of the application that executes on the server. However, they are much
more transparent than traditional Web applications, and this transparency provides
opportunities for hackers, as we will demonstrate over the course of the chapter.
It is possible to obfuscate JavaScript, but this is different than
encryption. Encrypted code is impossible to read until the correct key is
used to decrypt it, at which point it is readable by anyone. Encrypted code
cannot be executed until it is decrypted. On the other hand, obfuscated
code is still executable as-is. All the obfuscation process accomplishes is
to make the code more difficult to read by a human. The key phrases
here are that obfuscation makes code “more difficult” for a human to read,
while encryption makes it “impossible”, or at least virtually impossible.
Someone with enough time and patience could still reverse-engineer the
obfuscated code. As we saw in Chapter 2, Eve created a program to deobfuscate
JavaScript. In actuality, the authors created this tool, and it only
took a few days. For this reason, obfuscation should be considered more
of a speed bump than a roadblock for a hacker: it may slow a determined
attacker down but it will not stop him.
In general, white box systems are easier to attack than black box
systems because their source code is more transparent. Remember that
attackers thrive on information. A large percentage of the time that a
hacker spends attacking a Web site is not actually spent sending
malicious requests, but rather analyzing it to determine how it works. If
the application freely provides details of its implementation, this task is
greatly simplified. Let’s continue the weather forecasting Web site
example and evaluate it from an application logic transparency point of
view.
Monday, April 13, 2009
Subscribe to:
Posts (Atom)