In modern web applications is expected that the implementation is more JavaScript based, so that its users have a more interactive experience. ASP.NET provides a few ways to the programmer to perform asynchronous requests to the web server.
In this article, we will discuss what ASP.NET offers and a few tips on how to use them. Finally we will leave ASP.NET and see how we can achieve the same functionality with jQuery.
Update Panels
Update panels are the oldest trick in the book for ASP.NET. It is the simplest way to have ajax functionality in your web application. We will not see them in depth, just mention a few basic points about them. Below is a simple example:
<asp:UpdatePanel ID="SimpleUpdatePanel" runat="server"> <ContentTemplate> <asp:Button ID="AjaxButton" runat="server" Text="Button" /> <asp:Literal ID="MessageLiteral" runat="server"></asp:Literal> </ContentTemplate> </asp:UpdatePanel>
Protected Sub AjaxButton_Click(sender As Object, e As EventArgs) Handles AjaxButton.Click MessageLiteral.Text = "Ajax update occured" End Sub
In code behind, you have access to the entire form. That is possible because when an update panel refreshes, the whole form is been posted to the web server. But only the markup of the update panel can change. So, if we try to change something that it is not inside our update panel the change will not happen.
It is that simple to have ajax functionality in your web application. We can also assign some event handlers so when an update panel refreshes we can execute some JavaScript code.
var prm = Sys.WebForms.PageRequestManager.getInstance(); prm.add_beginRequest(BeginRequestHandler); prm.add_endRequest(EndRequestHandler); function BeginRequestHandler(sender, args) { //code that runs when an UpdatePanel starts refreshing } function EndRequestHandler(sender, args) { //code that runs when an UpdatePanel has refreshed. }
With that level of abstraction, it is pretty clear than it is not a very optimal approach. If an update panel encloses a big part of the web form, it will be much slower. Even having a small update panel, the whole form is posted to the server, including the ViewState.
Generally it is not a good practice to have nested update panels in a big depth (up to 2 is generally ok). Finally, different update panels cannot refresh simultaneously. You can read about it (and a workaround for it) here.
Page Methods
With update panels we can update html sections of our web page. There is no direct way to get a value (e.g. a string or an integer) via ajax. For that, we can use page methods.
Page methods are static methods declared in code behind and are exposed via JavaScript int the client. Page methods are much more lightweight since they don’t post nothing from the form, except what necessary parameters each method has.
In the following example you see a sample page method. You have to enable page methods in the ScriptManager. When calling the method in JavaScript you can set two function as attributes that will behave as success and error handlers of the ajax call.
ASP.NET part
<form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"> </asp:ScriptManager> <div> <asp:Button ID="PageMethodButton" runat="server" Text="Call Page Method" OnClientClick="javascript:call_page_method(); return false;" /> </div> </form>
JavaScript part
function success(data) { alert(data); } function error() { ... } function call_page_method() { PageMethods.HelloWorld(false, success, error); }
Code Behind part (vb.net)
Imports System.Web.Services Public Class _default Inherits System.Web.UI.Page ... <WebMethod()> _ Public Shared Function HelloWorld(ByVal LowerCase As Boolean) As String If (LowerCase) Then Return ("Hello World").ToLower Return "Hello World" End Function End Class
Page methods are lightweight. One disadvantage is that we can only use them in .aspx pages. We cannot declare a page method in a user control. Also, the JavaScript declaration of the method is embedded directly into the HTML. So, having many page methods will lead to bigger HTML files. Also, there is no way to declare them in a single place so that our entire web application can make use of them.
Web Methods
Page methods can be very useful and practical. In the scenarios where we would like to have such methods declared globally we can use Web methods. We can declare our methods in a .asmx file. When we create the new .asmx file we need to uncomment one line of code, as the comments on the top of the page suggest.
Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.ComponentModel ' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. <System.Web.Script.Services.ScriptService()> _ <System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _ <System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ <ToolboxItem(False)> _ Public Class myMethods Inherits System.Web.Services.WebService <WebMethod()> _ Public Shared Function HelloWorld(ByVal LowerCase As Boolean) As String If (LowerCase) Then Return ("Hello World").ToLower Return "Hello World" End Function End Class
In order to use the declared web methods, we need to register the .asmx service to our script manager. This can be in the asp.net markup or in the code behind.
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/myMethods.asmx" /> </Services> </asp:ScriptManager>
Finally, to use the web method in our JavaScript code we need to write the full namespace. For example:
function call_web_method() { DemoWebApplication.myMethods.HelloWorld(true, success, error); }
jQuery ajax
With jQuery you can also make asynchronous calls to the server and gives you more flexibility while developing your application. You can see and example of jQuery.ajax in the following snippet.
jQuery.ajax({ url: '/ajax_handlers/example-handler.ashx', context: document.body, cache: false, type: 'GET'; contentType: 'application/json', success: function (data) { var server_response = data; //This is the data the server returned }, error: handle_ajax_error }); // Here is a error handler stating some useful values regarding the error occured. function handle_ajax_error(xhr, ajaxOptions, thrownError) { alert('error: ' + xhr.responseText + '__' + thrownError + '__' + xhr.statusText); }
There are a couple of things to consider. One is that you may get errors if the response’s data type is not what jQuery expects. Also, you should use the ‘cache’ property and set it to false when you expect fresh data from the server. It’s default value is true.
For more information and options you can visit the documentation page for jQuery.ajax.
Comparing approaches
The main question that could rise here is what approach should someone use. In every case there are some advantages and disadvantages. With ASP.NET tools the development is a bit easier and faster. With jQuery there are some issues that the developer will need to address (contentType issues, encoding issues, etc) while the ASP.NET tools handle these things internally.
One disadvantage of the ASP.NET approach is that in any case the page must have one big form (runat=”server”). In a busy website this element might be better to be omitted and so jQuery is the (only) way to go.
In any case, the developer should know how to use jQuery in any case, since it is also used in ASP.NET MVC and most important it is not platform specific.
Related articles
We have seen how we can introduce ajax in our web application. The above article is an introduction for the above techniques. Below are a few articles related to the topic, that provide more specific information for them. The blog of Dave Ward has many useful and interesting articles regarding ASP.NET Ajax and jQuery.
- Why ASP.NET AJAX UpdatePanels are dangerous
- Simultaneous async requests with multiple Update Panels
- Using jQuery to directly call ASP.NET AJAX page methods
- Easily refresh an UpdatePanel, using JavaScript
Note: If you noticed the navigation function between the sections and the menu and liked it, you can check it out in this post: jSmooth – A jQuery plugin.
This article is great 🙂
thanks for sharing !
Awesome article, I learned a lot from it.
If all of your web pages inherit from System.Web.UI.Page in the code behind you can have all of your page methods in the one place.
Create a base page class that inherits from System.Web.UI.Page.
Place all page methods in this base page.
Change your websites code behind to inherit from your new base page instead of System.Web.UI.Page.
Thanks for the article. Good information!
Maybe you can help me understand something I am running into with my page. I am trying to run an async ajax call via jQuery in parallel to a normal button click event on a button inside an update panel. The ajax call runs async and I exit my javascript (jquery) method, however, the normal button click event does not fire until the web method returns.
Any ideas on why the web method isn’t running async and how I can get those to run in parallel?
Hey Will,
This seems a bit odd. Ajax calls in JavaScript are asynchronous by default. If you still haven’t figured it out, make a post in Stack Overflow with some code and post here the link so that I can take a look.