Now, this one is going to be a short list with lengthy descriptions of the different ways to make a request to the server, along with some benefits and peculiarities they have. I am not going to get in the full details, the net is full of articles on implementing this and that, I just wanted to clear some confusion that I have been noticing in the names that are used.
Also known as “Callback”. Or at least this is how it is supposed to be. I see people using the term callback for everything, primarily a partial postback (a word on them – later) and I don’t like it. It has its own distinct meaning and is a special kind of POST with its own specifics.
Put shortly, you need to implement the ICallBackEventHandler interface:
And register your control through the Page.ClientScript.GetCallbackEventReference() method during Page_Load.
WebForm_DoCallback(UniqueIdOfTheControl, argument, responseHandler, context, errorHandler, useAsync);
//use the data for the response
//use the data for the error
Everything is done by the framework for you, because this function is the client-side counterpart to the GetCallbackEventReference server method.
This type of request seems a bit obscure, yet I think it has a lot to offer:
- It does not go through the render phase of your page, it stops right after the Load events, so it spares a lot of work for the server
- It posts the entire page (including form values and ViewSate), so the code-behind knows what is happening in the browser and can use controls’ data
- It returns only the string you tell it to return, no ViewState, no scripts, no markup. Posting the page does not get lighter than this
There is always a catch – it does not mix well with other requests, so you should avoid using a callback inside an UpdatePanel, for example. Another thing you can have issues with is IScriptControls – they require some scripts in the response (read – the $create() statement) and this will not work inside a Client Callback.
In a nutshell – use a callback to get some simple data from the server while keeping it aware of the current state of the page.
It’s only a few lines, give it a try and inspect the request-response that is generated, and be amazed :) To make this easier I have attached a small page that shows the simplest approach here.
I took quite some time with this, so now follows its closest relative
Also known as AJAX request, and mistakenly dubbed callback.
This is perhaps the best-known one because it seems to be the simplest to begin using. Just add UpdatePanels, right? But not quite. It has its tricky moments like toggling the UpdateMode, paying attention to avoid nesting UpdatePanels, preventing a new request before the previous has ended because they will cancel each other out, etc.
Still, it is rather straightforward to use and does what you would expect
- Posts the entire page, so the server knows what you have in the browser
- Sends back only the relevant markup and scripts, and the ViewState
- Keeps the page responsive because it does not dispose it until the response comes, even then only the updated parts are disposed
Its main problem is that it actually executes all your code-behind and then renders the entire page on the server, even if it only has to send back a few lines of HTML. It is, essentially, a normal postback that does not send the entire page to the browser. Thus, its performance benefits are sometimes questionable, even if it offers much better usability for the client.
Well, it is here just so you don’t say I missed it. We all know it – everything goes up, everything comes done, the user waits and waits and waits. The response starts with the doctype and ends with </html>. Need I say more?
So, we are getting to the rest of the interesting ones:
Mark your static method with the [WebMethod] attribute:
PageMethods.myPageMethod(arg, OnSucceeded, OnFailed);
Toggle your ScriptManager
- Does not bother to post the form data or ViewState. Posts a JSON string instead, so you can pass multiple parameters which makes it quite flexible.
- Does not render the page, so once again the server does less
- Returns a JSON string only, so you don’t need to care about ViewState and markup
- Does not know the context of your page, so you can’t use any controls you have in the class instance. It is a static member after all
- The Page class is still instantiated, so you go through Page_Init and Page_Load for example
WebService and WCF WebService
In a way similar to page methods, these are classes that do not care about your pages at all – they are separate and should be designed to take in data, process it and return the result, regardless of the page that called them.
Once again, the framework is very generous and gives us a simple method we can use to call webservices: Sys.Net.WebServiceProxy.invoke(). It takes parameters, method names and the location of your services files. Works for both asmx and svc files. For WCF services there is a simple way to call them after registering them with the ScriptManager Services in your page - MyApp.MyWCFServiceClass.MyMethod1(parameters);
The basics of creating a webservice are once again a few attributes - [WebService] for the class, and for the method itself - [WebMethod]. With the simplest setup you can pass a string to the service and get a string back.
WCF services are not much different, they only offer a lot more flexibility – you can use different HTTP verbs (e.g. GET, DELETE) and benefit from goodies like Data Contracts, easily working with different data formats and so on. They require a bit more setup before getting them to run, so I will leave this to you for homework. My colleagues Carl did a great job of describing this (and much more) in his post from last year: The Present and Future of Using JSON in WebForms.
Benefits from using a service:
- Does not care about your page, so you need not cater for dependencies
- Does not even instantiate your page
- You can call it from anywhere
- It’s fast
- Does not care about your page, so you need to make sure you pass sufficient information
- Takes some code to setup and call, then you have to handle the response. This can be a bit tricky if you don’t use simple strings
While we are at modern technologies take a look at
This is one of the things that caused great fuzz when it was released and for a good reason. Take a look at these two blogs
And tell me if I am wrong in saying why WebAPI is awesome:
- Easy to setup
- Offers a great number of capabilities that WCF services do
This came out quite longer than I expected and it merely scratches the surface of the subject. There is a lot more to be said about each form of request, but I hope this post can show you some neat ideas and open a few doors for you to apply this knowledge.
I took more time to explain the more obscure ones, so if you have anything to add – just leave a comment, it could easily make it into the post itself :)