Showing posts with label methods. Show all posts
Showing posts with label methods. Show all posts

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.

Calling a server side method from javascript without page methods

Hi everyone.

I'm trying to do some like this:

if (confirm("foo") == true) {

MyServerSideFunction();

}

Of course, I can call this function using PageMethods, but since this function in my code behind shold be static, I cannot call others methods inside my class.

Is there any way to call serer side methods without using PageMethods?

Thanks, and sorry for my bad english!

You can use ajax to call a webservice from javascript. Check out this article on how to do it:http://www.semenoff.dk/en/Code-Corner/ASP.Net.AJAX/WebService-From-JavaScript.aspx

Hope it helps


__doPostBack("ServerEventNameHere","");


Hi Everyone :)

@.Klaus Byskov Pedersen

I alread tryed using web services and it works fine, but it's not the case.

@.rpack79

Nice! It works! I noticed that I had to catch this requent inside my OnPageLoad and call the appropriated methods. Now one more question: And if I want do catch this postback inside an WebControl? Actualy I'm catching the postback event inside my control's OnInit event. Is it the right way?

Thanks a lot by the answers.

Monday, March 26, 2012

call web services using bridging (ajax beta 2)

I have several web service methods(implemented in .net 1.1) to call, in a different domain. The response I get when callin any methods from this web service is the page I see at the URL where .asmx is located. The .asbx is:

<bridge namespace="Support" className="OLOS" ><proxy type="Microsoft.Web.Preview.Services.BridgeRestProxy" serviceUrl="http://suppsite/SuppServices/OLOS.asmx" /><method name="getGeodisInfo" ><input><parameter name="OrderInformation" /><parameter name="BUID" /></input></method><method name="getExpeditorsInfo" ><input><parameter name="OrderInformation"/><parameter name="BUID" /></input></method></bridge>

And the .aspx file:

.............. <asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/OLOS.asbx" /> </Services> </asp:ScriptManager>..............Support.OLOS.getGeodisInfo({ 'OrderInformation' : txtSearchText.value, 'BUID' : ' ' }, OnSucessgetGeodisInfo, OnError, "OLOS Search");.............. function OnSucessgetGeodisInfo(result) { if (result != null) { var resultText = result; document.getElementById('res1').innerHTML = resultText; } }
 
In the innerHTML of the DIV where I show results I get the content from the page located athttp://suppsite/SuppServices/OLOS.asmx
I do not see the actual call to the web method being done. Fiddler shows a call tohttp://suppsite/CareServiceCall/OLOS.asbx/js/getGeodisInfo but the response... does not contain what the method should return...
Any ideas?
Thanks

So I'm guessing your service url for the Asmx endpoint should behttp://suppsite/SuppServices/OLOS.asmx/<method>. What you'll need to do, is implement a TransformRequest in your Bridge codebehind, and as part of this, you need to set the ServiceUrl of the BridgeRequestl on the BridgeContext to the correct serviceUrl for your method. Since this is asmx, I imagine what you want to do is something like:

public override void TransformRequest() {
BridgeRequest.ServiceUrl = BridgeRequest.ServiceUrl + "/" + BridgeRequest.Method;
base.TransformRequest();
}

Hope that helps,
-Hao


Thanks for the response. Indeed that woulddefinitely help, at least a little bit later in the development phase.

What I am actually trying to do here is: I want to have all the methods for this web service(http://suppsite/SuppServices/OLOS.asmx/) defined in the same .asbx.

I know that changing serviceUrl tohttp://suppsite/SuppServices/OLOS.asmx/getGeodisInfo does the job, but then the rest of the methods defined in the .asbx are not callable. Using the url suffixed with the method name, works only if the web service has GET support, otherwise is not working for me. I also need to get this working when the web service works with POST only. I currently do not need transforms for method returns... at least not for all of them.

Is there a way to define in the same .asbx multiple methods and use them from javascript(except the way provided in the above sample)?


What I posted below dynamically changes the serviceUrl for each bridge request to be the correct one based on the method being called, which indeed it only works for GET, but if you want to support POST for asmx, you will need to build your own Proxy type for the bridge to make POST requests in the format ASMX expects, as the RestProxy only supports GET requests.

Hope that helps,
-Hao


Thanks Hao, everything is crystal clear now.

Call Remote WebService. "Parameter count mismatch" Error

Hello All, I.m using AJAX for call remote WS. For example WS placed on localhost.

1) Here some web methods from WS (AJAXBridgeService WebSite)

  
 [WebMethod]
public string HelloWorld()
{
return"Hello World";
}

[WebMethod]
public Account GetAccountByID(int ID)
{
return new Account();
}

[WebMethod]
public string GetStringByID(int ID)
{
return ID.ToString();
}

[WebMethod]
public int GetIntByID(int ID)
{
return ID;
}

  2) i generated proxy class with wsdl utility and place it in App_Code (AJAXBridge WebSite) 
 3) i created asbx file

<bridge namespace="AJAXTest" className="Class">
<!-- change url to required --> <proxy type="AJAXTest.Service, App_Code"
serviceUrl="http://localhost/AjaxBridgeService/Service.asmx" /
<method name="HelloWorld"/
<method name="GetAccountByID">
<input>
<parameter name="ID"/>
</input>
</method
<method name="GetStringByID">
<input>
<parameter name="ID"/>
</input>
</method
<method name="GetIntByID">
<input>
<parameter name="ID"/>
</input>
</method>
</bridge>

 
4) then i used the following HTML+JS code 
<asp:ScriptManager ID="PageScriptManager"
runat="server"
LoadScriptsBeforeUI="False"
EnablePartialRendering="True">
<Services>
<asp:ServiceReference Path="bridges/bridge.asbx" />
</Services
<Scripts>
<asp:ScriptReference Path="bridge.js" />
</Scripts>
</asp:ScriptManager
<a href="javascript:void(0);" onclick="javascript:Click1();">Click Me 1</a> <span id="span1"></span>
<br/>
<a href="javascript:void(0);" onclick="javascript:Click2();">Click Me 2</a> <span id="span2"></span>
<br/>
<a href="javascript:void(0);" onclick="javascript:Click3();">Click Me 3</a> <span id="span3"></span
JS:
function Click1()
{
AJAXTest.Class.HelloWorld({}, OnComplete1, onError1);
}

function OnComplete1(obj)
{
var span = $get('span1');
span.innerHTML = obj;
}

function onError1(obj)
{
var span = $get('span1');
span.innerHTML = "Error:" + obj.get_message;
}

function Click2()
{
AJAXTest.Class.GetAccountByID({"ID" : 1}, OnComplete2, onError2);
}

function OnComplete2(obj)
{
var span = $get('span2');
span.innerHTML = obj;
}

function onError2(obj)
{
var span = $get('span2');
span.innerHTML = "Error:" + obj.get_message();
}

function Click3()
{
AJAXTest.Class.GetStringByID({"ID" : 100}, OnComplete3, onError3);
}

function OnComplete3(obj)
{
var span = $get('span3');
span.innerHTML = obj;
}

function onError3(obj)
{
var span = $get('span3');
span.innerHTML = "Error:" + obj.get_message();
}

 
5) After press "Click Me 1" link, i invoke HelloWorld and it returned string value to span,
then if i press "Click Me 2" or "Click Me 3"links, i got OnError and error message with "Parameter count mismacth".
There is a topic like thishttp://forums.asp.net/t/1136077.aspx
Does have anybody any information about call bridge with parameters? 
 
 
 
 
 



  
 
  


You may remove the jason-styled parameters.

In your javascript service invocation you may send the number only before the callbacks at this syntax:

AJAXTest.Class.GetAccountByID(1, OnComplete2, onError2);
(instead of AJAXTest.Class.GetAccountByID({"ID" : 1}, OnComplete2, onError2); )

Note: Don't send date this form, (you may send string instead and parse it on server side)


Vinija:

You may remove the jason-styled parameters.

In your javascript service invocation you may send the number only before the callbacks at this syntax:

? AJAXTest.Class.GetAccountByID(1, OnComplete2, onError2);
(instead of? AJAXTest.Class.GetAccountByID({"ID" : 1}, OnComplete2, onError2); )

Note: Don't send date this form, (you may send string instead and parse it on server side)

?

There we call remote web service via bridges technology, which demand of JSON input parameter.

I'm mot realy familiar with JSON syntax but according to the article you've referenced to, it seems that
you shouldn't write ID in quotation marks but simply write the word ID.

I'm not sure if it'll help you (you may have tried it already) but this is what I can see that by be wrong.

About the JSON input parameter, shouldn't the AJAX engine imlement the JSON serialization without
you actually write the parameters JSON styled?


<method name="HelloWorld"/
<method name="GetAccountByID">
<input>
<parameter name="ID"/> see here ...the parameter name is the same for all !!!has it got to be different?try and see it does not knw which parameter to invoke when clicked ,probably this might be an error
</input>
</method
<method name="GetStringByID">
<input>
<parameter name="ID"/>
</input>
</method
<method name="GetIntByID">
<input>
<parameter name="ID"/>
</input>
</method>
</bridge>

cheers

shankar