RSS

Monthly Archives: May 2011

A quick guide to have jQuery call your ASP.NET PageMethods

I based most of my solution and understandings on several posts from Dave Ward. Although Dave’s excellent posts cover everything written here and more, it still took me quite a while to get this going. That is why I decided to sum up my current experience in this single post, which may be considered as a quick guide to having jQuery call WebMethods (PageMethods in particular).

Assuming that we have the following PageMethod, how do we use jQuery to call it?

There are several stages I had to go in order to use jQuery alongside PageMethods:

  1. Use the correct url for the PageMethod.
  2. Ensure that the client and server use json content types.
  3. Pass arguments to the PageMethod as JSON strings (see the ‘JSON, objects, and strings: oh my!‘).
  4. Interpret the result using the ‘d’ key (see the ‘Waiter, there’s a .d in my msg soup!‘).

Here’s the client code I ended up with (explanation below):

Correct url? No surprises here. In order to invoke the correct PageMethod you have to supply a valid url for that method. It’s easy to use ResolveUrl to get this right.

json: As you can see, I used jQuery’s ajaxSetup method in order to assure that all ajax calls are sent using json. Naturally, you don’t have to do this if you do not want JSON, or if not your calls are json-based. But, no doubt that placing the ajaxSetup call in a js file that gets loaded from a master page is very comfortable to ensure that all your jQuery ajax calls are using the same basis.

JSON arguments: This is the part where it get tricky. As Dave Ward explains so well in his post, ASP.NET expects arguments in JSON format, whereas jQuery sends JavaScript objects (which are mistaken for JSON objects) in query string format (that is, if you try to send JavaScript objects). This means that you have to provide jQuery not with a JavaScript object, but rather with a proper JSON string. This will ensure that jQuery wont parametrize your data in key=value format and will provide ASP.NET the desired JSON format. This is important because it means that if you decide to pass your data object as an invalid JSON string, you’ll be frustrated why the thing isn’t working. That’s why when I learned of the JSON native support that now exists in the popular browsers (IE8, FF 3.5 etc.), it became an obvious solution: using JSON.stringify() ensures that the data gets sent in proper JSON format.

Whats with the ‘d’? As explained in Dave’s post, ASP.NET 3.5 and onwards returns a JSON response from the server with a key of ‘d’, for security purposes (preventing XSS attacks). While ASP.NET Ajax framework automatically handles the new ‘d’ formatted result, so that you’ll end up with the intended data without ever knowing that a ‘d’ was there in the first place, you have to handle this manually when using jQuery and WebMethods. jQuery’s combination of ajaxSetup and dataFilter event allows us to handle response from the server prior to actually calling your “onsuccess” callbacks. The proposed solution in the code above assumes that our site is working only with ASP.NET 3.5 WebMethods, and therefore a ‘d’ is always returned. I believe that usually that will be the case, although a more complex solution for checking if a ‘d’ is there already exists. Anyway, the proposed solution simply takes a JSON string returned from from the server, parses it and extracts the actual data from the ‘d’ key. It then transforms the actual data back to a string (which is what jQuery will expect to get when the dataFilter event has ended…).

Following the described steps should get you to use jQuery with ASP.NET’s WebMethods and PageMethods.

After this has consumed precious time to get going, the big question that remains is: was it worth it. You could argue that using jQuery is faster, or that it seems like MS’s client framework is destined to “retire” in favor of jQuery. But honestly, having to go through all this trouble for calling a PageMethod just seems way too much. In short, personally, I’d rather have the good old script proxies which are extremely easy to use over the not-so-trivial jQuery alternative.

Just a reminder though: in MVC using jQuery is quite trivial.

 
2 Comments

Posted by on 20/05/2011 in Software Development

 

Tags: , , , ,

MVC and posting data using Html.BeginForm and Url Routing

We all have pages which represent “fill in” data forms. Quite common is a user’s details form: what’s your first name, what’s your last name, email, date of birth etc. This can be coded in various ways, but I thought that this would be a good way to get to know ASP.NET MVC’s Html.BeginForm( ). While there’s also an Ajax.BeginForm(), I think that the two may differ mainly in the desired behavior after you have completed posting and saving the form data. For example, if you’d like to redirect your user to some other view, or display an entirely new View altogether, you might prefer using Html.BeginForm( ). However, you may want to simply display an informatory “Saved successfully” message, and in that case you’d probably consider using Ajax.BeginForm( ) or simply jQuery’s post.

The thing is that Routing could make this a little tricky (as it was in my case). If a certain Route led to a Controller and resulted in a View with a “fill in” details form, the generated html Form’s Action attribute is going to be that exact route which you originally used. So how on earth are you supposed to save your data, if the same route was used to originally render your details in the first place? Sounds confusing? I also thought so till I figured it out. Lets clarify this issue with a real world example. Suppose your website allows users to view and edit their personal profile. Your route could be like so:

Users would be able to use: http://<server or site name>/profile/myUsername to view and edit their profile. Our server side code residing in the AccountController is the following:

Note that the controller has a LoadProfile action method (which corresponds to the route action shown earlier), and a SaveProfile action method. In order to have the form data posted to SaveProfile, we need to provide some arguments to Html.BeginForm( ):

Basically, this works. The View renders fine, the submit button posts the data to SaveProfile as expected and everything seems great. But, I’m only missing one thing: I don’t have the original username from which the Form originally rendered. In order words, I have no idea at this time to which user the filled in data relates to. This was available from the Route url when the profile was loaded, but it’s unavailable now, when Html.BeginForm( ) uses custom data for posting. I thought that this would be easy to accomplish, because the Html.BeginForm( ) has overloads which accept routing data, but it turned out that when I provided those, other Routes I have in my application got prioritized and this gets ugly, because it means that I’ll have to provide more routes or route constraints in order for this to work. And this was just one form in my app, and it doesn’t make sense that I’ll have to do this for all the forms I’ll develop.

This led me to a different question altogether: Why should I explicitly supply BeginForm( ) with an action or controller in the first place? How come that in MVC’s templates there aren’t such arguments when calling Html.BeginForm( ), and yet when posting data, the correct action is invoked? I noticed that if I provided no arguments to Html.BeginForm( ), the default action was a “profile/{username}” route, just like what I used for loading the user’s profile. I was puzzled over this, because I didn’t understand how MVC was supposed to differentiate between loading a profile and saving a profile, as the Route used for both operations is identical. I looked up MVC’s template and found an example for ChangePassword. Turns out that there are a couple of ChangePassword( ) overloads. The first overload received no arguments (for “loading” the form), but the second overload received a Model with the data (“saving” the form). So how does the route knows which method should be invoked?

The answer lies in an [HttpPost] attribute which is placed over the “saving” action method. The route is quite clever and the action type (either GET or POST) is used to differentiate between actions of the same name. This makes sense, because usually a GET operation is to be used for loading a form, and a POST operation is usually used to posting and saving a form. I went ahead and tried it: I removed the arguments from Html.BeginForm( ), changed LoadProfile and SaveProfile action methods simply to “Profile“, added [HttpPost] to the Profile action method which performs the saving operation, and changed the route accordingly. Here’s how this looks:

If we use two action methods by the same name without [HttpPost] on one of them, the run-time throws a “The current request for action ‘Profile’ on controller type ‘AccountController’ is ambiguous between the following action methods” exception.

Now I could use the RouteData collection for retrieving the user name, as well as other form fields which were sent over as arguments.

 
4 Comments

Posted by on 09/05/2011 in Software Development

 

Tags: , , , , , ,

C# 5 – await and async in ASP.NET

I’ve been doing some reading and experimenting with the new C# 5 Async CTP, available for download from here. I guess that the Async Framework will be a part of .NET 5, although I haven’t found a formal document stating so. There are also some blogs released in the past few months by MS’ people that share information about this new feature. I’ll try to summarize it as I understand it for now, and specifically relate to my findings with regards to ASP.NET.

C# 5 Async Framework seems to focus on easing asynchronous programming. It seems like MS has decided to help us developers write asynchronous code without having to deal with the technical aspect of things, mainly callbacks or thread management, and focus instead on the actual logic we need to implement. The basic idea is that a developer may write code “more or less” in a synchronous fashion, and for the Async Framework to do the rest. In my opinion, this does not mean that a developer won’t have to understand the concept of async programming, nor does it mean that a developer will cease using other “orthodox” methods of async programming.

Having said that, here is an example based on MS Async Whitepapers of how it looks. First, lets review a normal nowadays synchronous method for downloading images and saving them on the local machine, using ASP.NET WebForms Page:


Let’s quickly go over this:

  • Lines 16-19 represent Urls of images for download.
  • Lines 22-25 iterate over the Urls, calling a synchronous method per Url.
  • Lines 30-37 is the method which downloads the given Url synchronously using a simple WebClient (I’ve omitted IDispose handling in this post for simplicity).

The Async CTP allows us to transform this code into asynchronous code by performing minor changes:

For the moment we’ll skip the Page_Load implementation and go directly to the downloading method (lines 27-34). We can see very clearly that the implementation remains almost identical to the original method. However, the Async CTP has some new keywords in C# 5 which are used here, that instruct the compiler to compile our code differently behind the scenes. These are async and await:

  • async: This tells the compiler to compile our method differently, so that it uses Tasks and callbacks to run. Although async is mandatory for using awaits, basically its useless without having any awaits in it. This means that if an asynced method has no await instructions within, the method runs synchronously as usual. Writing async in a method doesn’t cause it to be run on a different thread at all (as you might have expected). All it does is to instruct the compiler to auto-generate hidden classes behind the scenes in order to support awaits.
  • await is what actually tells the compiler to auto-generate code using Tasks in order to run asynchronously. An async method’s code is executed on the same thread it was called upon, until it gets to the first await. Every await (starting with the first one) executes and returns immediately. Once again, this may be confusing with nowadays Wait( ) methods which usually block threads. This isn’t the case here. await does the opposite – it causes the compiler to auto-generate code which runs the code asynchronously, while preserving the context of the method. The rest of the method is compiled as a callback of the async Task. When the Task has completed, the code resumes execution using the synchronization context “right where it left off”. The Async CTP Whitepaper is very clear on this: “At first glance the await keyword looks like it blocks the thread until the task is complete and the data is available, but it doesn’t. Instead it signs up the rest of the method as a callback on the task, and immediately returns. When the awaited task eventually completes, it will invoke that callback and thus resume the execution of the method right where it left off!”

Now that we understand what async and await are, we can understand lines 27-34 better. The highlighted changes are:

  • Line 27 contains two method signature changes: async was added in order to “tell” the compiler that this method is going to use the Async framework; The Task return class is the real deal here, because it’s what allows the calling code to query the status of the async task.
  • Line 30 also contains two changes: await performs an async call to DownloadDataTaskAsync, which returns, that’s right, a Task. In the Whitepaper’s terminology, we “await the task”.
  • Lines 31-33 is compiled as a callback for the Task. This code will not be executed until line 30 completes.

With minor changes to the code, our previously synchronous method has become asynchronous! What’s quite amazing here is that the code still looks as if it is synchronous. This means that in the future, it’s supposed to be much easier to write code asynchronously. Let’s go over the calling code now:

  • Line 14 has a new async which “tells” the compiler we’re using Async framework in this method.
  • Line 22 uses await, which basically what starts the async operation and awaits completion, but what’s more important is that we use a parallel new feature, TaskEx.WhenAll( ), which waits till all the tasks have completed (sort of a Thread.Join for all the Tasks). The TaskEx is the temp CTP class and the WhenAll method is expected to be a part of the Task class upon release.
    • We have to await TaskEx.WhenAll( ) or the Stopwatch will be stopped immediately (line 23). Nevertheless, the Tasks will end as expected during the Page’s life-cycle – this will be explained later on.
  • Lines 23-24 are compiled as callbacks and will not be called till line 22 finishes awaiting the task.

One more thing we need to add here, is that just like in ASP.NET 2, running a code asynchronously requires us to have an Async=”true” in the @Page directive. Failure to do so will result in a: “Asynchronous operations are not allowed in this context. Page starting an asynchronous operation has to have the Async attribute set to true and an asynchronous operation can only be started on a page prior to PreRenderComplete event.“, which hints us not only at the Async=”true” directive, but also that the PreRenderComplete is somehow involved. I’ll discuss this later on.

Let’s have a quick view in Reflector at how this looks (we’ll focus on the Page_Load await):

  1. Notice that the MyForm page contains hidden elements which were auto-generated by the compiler. There’s now a <Page_Load>d__1 class which is used for the asynced Page_Load method (and there’s also a <AsyncDownloadFile>d__6 class for the asynced AsyncDownloadFile method). As you can see, the actual Page_Load method looks entirely different than the original source code.
  2. This statement is basically the what will used to perform the callback when the operation completes.
  3. MoveNext() actually starts execution (see below).

The above code shows us the auto-generated MoveNext() of the <Page_Load>d__1 class:

  1. This is our original code, initializing the Urls to be downloaded, as well as the Stopwatch which times the operation (the code which refers to GetExecutingAssembly was inserted by me in order to be able to easily detect where the compiled assembly is, and to Reflect it – so just ignore it.)
  2. That’s the awaiter.
  3. OnComplete, calls the callback (remember item #2 in the previous Reflector window?), which is the MoveNext() again, till the awaiter’s IsCompleted method returns true.
  4. This is the actual callback code – Stop the Stopwatch and display the elapsed time.

As you can see, our original code was split into 2 parts, one to be executed prior to the await, and the rest as callback code.

Life-cycle

Finally, let’s understand the life-cycle of things. I’ve added some code to log the different operations and thread creations. I also added two life-cycle events (PreRender and PreRenderComplete), because I wanted to learn how the life-cycle handles awaits and asyncs. This is a screenshot of the result:

Short explanation: The “Thread number” column is what’s important. It hints at whenever a new thread was assigned to handle the executing code, which actually means we can better understand the life-cycle of ASP.NET in an async scenario. Here are some highlights:

  • The first thread, which is assigned by ASP.NET to handle the request, is the one stated as “Page_Load thread”. As we can see, this thread executes all the code which runs just prior to the first await. Each await executes and returns immediately, and this can explain why both “before awaits” are on the same thread.
  • Important: OnPreRender wasn’t blocked. So now we know that asynced code which returned from the awaits continues unblocked and does not wait for the Tasks completion in the ASP.NET life-cycle, at least up to PreRender.
  • The first AsyncDownloadFile log message shows us that the callback is running on a different thread, as expected. So we know for sure that the async framework has indeed did what it was supposed to do, which it to split our original code into a block which runs on the calling thread, and a callback which runs on a different ThreadPool thread.
  • Note that the second AsyncDownloadFile log message shows us that a different thread handled the second url callback. That’s also “as expected”, as different Tasks handled each url.
  • As opposed to PreRender, we can see that PreRenderComplete executes after all awaiting Tasks have finished. This will be the behavior even if we remove the await from the TaskEx.WhenAll( ) call. That’s important, because we now understand that ASP.NET is involved in the life-cycle of things and takes care that we won’t finish the Page’s life-cycle before all Tasks are completed. This resembles ASP.NET 2 Async Page pattern (see summary below), and sheds light on the meaning of the detailed Exception specified earlier.

To summarize what we’ve seen so far, using the already existing Task classes, await starts an asynchronous operation and returns immediately. So, the code itself is not blocked at all. The compiler generates code also for the callback, so our code continues only when the Task has completed. In other words, async and await cause the compiler to compile our code into async Tasks and callbacks. ASP.NET integrates well with this environment and “knows” to await all tasks, if you haven’t done it yourself. Needless to say, the asynced version runs in parallel which makes it a lot faster.

If you feel like these async and await keywords are misused, you are welcome to join the arguments which seem to be taking place. As written previously, according to Eric Lippert’s post, developers misinterpret await for a blocking Wait-like operation, whereas it’s exactly the opposite, and tend to believe that writing async in the method signature means that .NET will run it asynchronously. However, as stated in Eric’s blog post, attempts to find better keywords so far have failed.

Summary

I find the suggested framework interesting as it will probably allow a somewhat “default” implementation of async programming, and will allow us developers to achieve async solutions more easily.

I think that many developers who know how to develop async programming to some extent, don’t actually do so. I even “dare” to think that this is a more common situation in server side web programming. Unlike Windows Forms development, where using a BackgroundWorker or some other threading solution is usually required in heavy duty tasks, but somewhat trivial because the forms stay in-memory for as long as we require them to, in server side web programming this is quite different. Most ASP.NET developers rely on IIS and ASP.NET to assign requests to threads, and know that if you initiate a multi-threaded operation yourself in ASP.NET, it is a pain. That’s because when you start a thread, the Page doesn’t stay in-memory or wait for it to finish. In Web Forms, the life-cycle doesn’t wait just because a developer opened a new thread in Page_Load or some other Button_Click event handler. The newly created thread will probably complete after the life-cycle has ended and the response was already sent to the client. More over, if you do implement a threading scenario in ASP.NET and block the page life-cycle using a Thread.Join or some other threading blocking mechanism, the actual ASP.NET main thread processing the request is stuck till the new thread has completed, and is not returned to the ThreadPool. That’s why the people at Microsoft have invented Async Pages in ASP.NET 2. This implementation was built on the idea that somewhere in the Page’s life-cycle (after PreRender), an async operation may start, the thread handling the request will be returned to the ThreadPool, and upon completion of the async thread, the life-cycle is resumed using a different ThreadPool thread (returning to the PreRenderComplete in the life-cycle). While this was some sort of a solution, it was still uncomfortable and forced to developer to be bound to a certain step in the life-cycle in order to achieve async in ASP.NET. So, my guess is that most developers chose not to use this solution as well. In short, while client side async programming evolved thanks to Ajax, server side web programming in ASP.NET lacked the proper infrastructure to evolve. Thanks to the Async framework, it’s possible we’ll see more async web server side development.


 
12 Comments

Posted by on 02/05/2011 in Software Development

 

Tags: , , , ,