Wednesday, March 28, 2012

Calling Asynchronous Web Services

How do I call an asynchronous Web Service, from AJAX, that has been defined according to this article:

How to: Create Asynchronous Web Service Methods

The AJAX Web Service proxy-generator creates Begin<MethodName> and End<MethodName>... methods instead of just <MethodName>.

Best Regards,
Michael Carr

1. On your web service class, place the attribute of [ScriptService]

2. Create your web method.

3. Call your web method from javascript at the following syntax:
<YourWebServiceName>.<YoureMethodName>(<parameter1>,<parameter2>,...,onSuccess, onError)
where onSuccess and onError are javascript functions acts as a callbacks to the web method. (you don't have to place
an onError callback however it is recommended)

4. Your onSuccess function shold receive your method returned value as a parameter and should look like that:
function onSuccess(result)
{
//Handle the method's returned value
}



Vinija, that's fine for "normal" web service methods, but I'm trying to call an asynchronous web service method as defined by the above-referenced document. In this case, the WSDL describing the method is <MethodName>, but the AJAX WebServiceProxy generated class creates only Begin<MethodName> and End<MethodName> stubs. So, your approach doesn't work in this case.


The question is, what is the purpose of making an asynchrnous call?

My approach describes an asynchronous call to web service from javascript (If it wasn't asynchronous there wouldn't be any
callbacks).

If the web service is remote and you need to create a proxy to it, all you have to do is copy the method names without
any prefixes and call the same method on the remote service from your copied method. Then you can add the [ScriptService]
attribute and call it from AJAX,

The above reference doesn't relate to AJAX but to regular asynchronous call. To do that you need to place two calls
for begin<Method> and end<Method> while calling the end<Method> will be in fact synchronous (you have to wait
for the method to end). However, If you don't want any responce, you might just call the begin<Method>, However,
toperform asynchronous calls from AJAX you realy don't need an "asynchronous proxy".


Ajax itself is Async, There is not benifit of creating that kind of WebService.


When using asynchronous web services does the "work" move to a new background thread or does it still remain on an ASP.NET thread? (A similar pattern to using an IHttpAsyncHandler.) If it does move to a non-ASP.NET thread then that would be a good reason to use the asynchronous web service pattern, even though AJAX is an asynchronous pattern as it provides scalability for the website because ASP.NET has a limited number of threads available.

But, again, I'm not sure if the work moves to a background thread in the asynchronous web service model.

Happy Coding.


Yes Rumerman you're exactly right. Somehow I wasn't able to convey that point in my earlier posts.Sad I think the earlier posters are perhaps confusing anasynchronous method (what I want to do) with anasynchronous call to a method (what they're describing). I am basically trying to implement for a web service (asmx) what the "Async" property of the @.Page directive implements for web forms (aspx).


I got ya... but there's no way to do it Sad

The RESTHandler that handles our request when we execute a client call to a web service method we've tagged as a ScriptMethod is synchronous. It implements IHttpHandler, not IHttpAsyncHandler.

I've gotten different responses from MSFT regarding why this is the case, but it seems that the consensus was that since the next version of ASP.NET AJAX supports calling WCF methods and those don't have to use ASP.NET threads anyways (they can live at an arbitrary endpoint not on the ASP.NET stack), then there wasn't a need to implement the RESTHandler using IHttpAsyncHandler because it would scale without moving the work to a background thread ... Now, my response to MSFT was, "wasn't WCF out before ASP.NET AJAX 1.0 dropped? (Yes.) Then why wasn't WCF supported to begin with?" Still waiting on an answer for that ... but most likely it'll be the so many features, so little time answer, which as a developer in the corporate world, I understand, even if I think this was a big missing feature.

So to answer your question, no, there is no direct exposure to the BeginWebMethodName, EndWebMethodNamethat you're asking about.


My understanding from the document I referenced in the first post of this thread was that asynchronous web methods are basically a server-side construct that provides a framework within which you can return a thread to the pool until some long-running process completes. Since this framework is established/handled within the server, it should have no bearing (I would suspect) on how the client calls the method. In fact, if you look at the WSDL created for the web service described in that document (or point your browser at webservice.asmx), you'll see that the WSDL has only <MethodName> defined and not Begin<MethodName> and End<MethodName>. This suggests to me that the client should see only <MethodName> and call it as it would any other web method.

I suspect that what's happening in this case is that AJAX's proxy-generating code is using reflection to get the web methods instead of WSDL, and as a result it's creating Begin<MethodName> and End<MethodName> when it should be creating only <MethodName>. If this is the case, fixing this behavior may be as simple as fixing the proxy-generating code to detect Begin<> and End<> methods (as the WSDL-generator does, evidently) and handle them accordingly.


korggy:

... asynchronous web methods are basically a server-side construct that provides a framework within which you can return a thread to the pool until some long-running process completes.

That's absolutely correct. Only MethodName is in the WSDL, and the handling of the Begin<MethodName> and End<MethodName> requests is done by an implementation of the IHttpAsyncHandler. When AJAX interrogates the web methods (using reflection, you are correct), it only sees the WebMethod, not the Begin/End version of the WebMethod. There are no Begin/End methods exposed to the client as REST callable methods. Since ASP.NET AJAX overrides the default Handler for web service methods when they come across in a REST format and doesn't use the built-in .NET WebServiceHandler (handler for *.asmx), the asynchronous capabilities of the WebServiceHandler (the ability to handle Begin* and End*) aren't available. Even if we fixed the proxy to spit out Begin* and End* methods, the RESTHandler wouldn't know what to do with those calls and would just look for a web method of that name.


I have the exact same issue. We are making a call to a web service that in some cases has to start a process that can take a few seconds to complete. With the high volume we are handling keeping that ASP.Net thread locked is not an option so we moved to an Async Web Method model. The problem is that everything works perfectly find when you use XML as the return type, as soon as you move to the JSON serialization you get a method not found when you look for MethodName. We are using jQuery to create the web service calls, so in this case we are using XML until we can get around the problem with JSON.

No comments:

Post a Comment