Thanks for the blessing :) This is my first attempt at publicing code as well as blogging so I'm a bit uncertain about the etiquette, does and don'ts.
Anyway... When trying to create an example of the error handling, I discovered two things:
1. A bug in the call queue. I goofed but now it's corrected.
2. The service allways returned the full response xml. For the moment, I just stripped it so that the content of the Response is returned. The goal is of course to analyse the wsdl and return properly converted data types (strings as strings, ints as ints and complex types as Objects or complex types when the type is registered with a Class alias). This is a project for the future :)
So download the new zip.
...and here is the example:
Service creation:
================================
protected function createService():void {
service = new WebService();
service.addEventListener(LoadEvent.LOAD, onWsdlLoad);
service.addEventListener(FaultEvent.FAULT, onWsdlLoadError);
service.loadWsdl("http://tech.manmachine.se/WebService.asmx?wsdl");
}
protected function onWsdlLoad(event:LoadEvent):void {
trace("wsdl loaded");
}
protected function onWsdlLoadError(event:FaultEvent):void {
trace("wsdl load error: " + event.fault);
}
Service call:
================================
protected function callService():void {
/*
Method 1
Assign IResponder to the AsyncToken
This class implements IResponder
Result is sent to result function and fault is sent to fault function
*/
var token1:AsyncToken = service.Hello("World");
token1.addResponder(this);
/*
Method 2
Listen to events on the AsyncToken
*/
var token2:AsyncToken = service.HelloObject("World");
token2.addEventListener(ResultEvent.RESULT, onResult);
token2.addEventListener(FaultEvent.FAULT, onFault);
}
public function result(data:*):void {
trace("result: " + data);
}
public function fault(info:*):void {
var f:Fault = info as Fault;
trace("fault: " + f);
}
public function onResult(event:ResultEvent):void {
trace("onResult: " + event.result);
}
public function onFault(event:FaultEvent):void {
trace("onFault: " + event.fault);
}
30 comments:
Great work! You and Carlo... Question: What exactly does this line of code do:
var token2:AsyncToken = service.HelloObject("World");
How is your web service written? Can you post that here?
Thanks
How do you go about parsing the XML result? You have, in your example, "function result(data:*):void{trace("result: " + data);}" and that returns "result: Hello World!". How did you get that individual string ("Hello WOrld")? Is that in relation to how your Web Service was written? I also noticed you have "--target--World--target--
--phrase--Hello World!--/phrase--" How did you get target and phrase in there? (-- = html brackets)
Answer 1:
The AsyncToken is the handle for the call. On to the token you can add listeners or listen for events. I demonstrated both methods. token2 is returned by the call for the HelloObject method. This method returns a custom object built with two properties.
Answer 2:
I do not really parse the result. I just return it. What SHOULD be done is that the WSDL parser should pick up the return type definition and cast the result properly. I just haven't had the time to build this yet.
About the web services: They are build with Visual Studio 2005 so everything except the actual methods and the custom Object class is auto generated.
Hi, this is great by the way! I am curious how the token thing works. I know you've already been asked about this but could you please explain in more detail how I would go about setting up a web service to use tokens?
Is it just a case of setting up two web services (1st with name of ws, 2nd with name of ws + object) then get the first ws to just return the name of the ws and the second to return the object xml for the 1st ws?
I look forward to your response!
Thanks, Alex
Hello Johan, I've downloaded the component you've put here, but i'm new in Actionscript 3.0 and I don't Know where to begin, how to use it, how to prove it. Do you have some step by step tutorial??
Thank you in advance
Marlon mjpena@bancaribe.com.ve
it works for me, but sometimes i get this error - "Error opening URL 'http://webservice.com/remoting/public.asmx'
onFault: [Fault (faultCode=ioError, faultString=Error #2032: Stream Error. URL: http://webservice.com/remoting/public.asmx, faultDetail=null)]"
I fixed a major bug in your class.
In WSProxy you have _busyOnCall = true; within callMethod()
and it gets set to false in onComplete()
but it NEVER GETS SET IN onFault
This frustrated me to no end for days.
hi there.. i tried to use your example but it says interface IResponder was not found...
i havent's changed nothing in fla or document class...little help here?
probably you had changed the name of folders that contains .as files... if you want i can send you my modification of that webservices, for me they work wery good! thanks to the author! :)
#hobbbz
you can describe your fix, or how we can do it.. if it possible..
To expand on hobbbz findings - the issue surfaces when your web service returns an error (eg you pass it unexpected parameters). Further calls with valid parameters will not work. Thats because _busyOnCall remains true in the event of an exception. Simple fix is to add the following line in WSProxy.as class file
private function onError(event:Event):void {
_busyOnCall = false;
var fault:Fault;
if(event is IOErrorEvent) {
var ioee:IOErrorEvent = event as IOErrorEvent;
fault = new Fault(ioee.type, ioee.text);
} else {
var see:SecurityErrorEvent = event as SecurityErrorEvent;
fault = new Fault(see.type, see.text);
}
var faultEvent:FaultEvent = new FaultEvent(FaultEvent.FAULT, false, true, fault, _token);
_token.dispatchEvent(faultEvent);
}
Flash Player Version Alert!
We had used Carlos' original class in a site earlier this year. We started to hear complaints that the service would just sit and spin and never do anything. However we couldn't recreate the issue....until recently.
There were security changes in Flash Player versions sometime around version 9.0.120.0, so versions prior to that (like 9.0.42.0) worked fine, versions after that (like 9.0.124.0) fail.
The solution is to add a new item to the crossdomain.xml file, that looks like this:
{allow-http-request-headers-from domain="[your domain]" headers="SOAPAction"/}
Previously all we had in the crossdomain.xml was this:
{allow-access-from domain="[your domain]" /}
We'll definitely be trying out your extension to this class for error/fault checking, so future changes to Flash can be caught instead of leaving the visitor hanging.
Thanks for the great work!
NOTE: blog wouldn't let me use greater than and less than signs above, so I replaced with curly brackets.
I've found that if the web service times out, the proxy object is left in a busy state. Any further calls, simply get queued up and don't get called, so you cannot simply retry the method call. This also occurs even if you recreate the service object and reconnect to the service, because the proxy object is a singleton, and thus still marked as busy. I'm modifying my local version by adding a method to the proxy which allows you to delete the static instance, so that it's recreated next time it's requested. A better solution may exist though...
Oh nevermind, I see that hobbbz already addressed this issue with a better solution than what I suggested. (setting _busyOnCall to false within the onError handler)
Hey guys is it possible to fetch data from this url using your class http://arcweb.esri.com/services/v2/RouteFinder.wsdl > if yes then how Iam unable to do it. but it works fine with AS2 webservice class.....
Here is an example of parsing simple SOAP response.
public function result(data:*):void {
// wsdl has finished loading.
trace("wsdl loaded and parsed");
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*
*
* Once this returns VALID XML, should be able to just call
* convertXML(data) and call it a day!
*
* */
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
var xmlString = XMLList(data);
xmlString.ignoreWhitespace = true;
// convert it to a string
xmlString = xmlString.toXMLString();
// define the regex pattern to remove the namespaces from the string
var xmlnsPattern = new RegExp("xmlns[^\"]*\"[^\"]*\"", "gi");
// remove the namespaces from the string representation of the XML
var namespaceRemovedXML = xmlString.replace(xmlnsPattern, "").replace(/</g, "<").replace(/>/g, ">");
// set the string rep. of the XML back to real XML
var responseXML = new XMLList(namespaceRemovedXML);
//Now you can use e4x on responseXML
}
hi, this is a great work otherwise its really frustrating to make serialize and unserialize webservice calls on AS3.i m using it right now ad it works fine but i like to ask few things;
1. how can i pass complex objects (e.g. Arrays or objects) as agrs in callService Mehtod? for single args like string & Int type it is working fine but when i pass an array then I wont be able to receive it on the server.
2. Is it possible to receive a complex object in response or the Response must be in XML format?
Plz elaborate it.
thanks haris
Hello, I was searching the net for a solution for the Webservice problem. And very glad I found this finally :)
In as2 I worked with a Secured Webservice, is this also possible with you class? I worked with SOAP autentication header? How can I work the same way or how can I solve my problem?
Hey bert can u explaine me abt connecting to secure webservice in AS2 please I was searching for it quite a long was not able to find one.. please help me
smilehari@gmail.com can u send a mail 2 me also if possible
Thank you for your effort and for publishing this.
You just saved me so much time! I would have had to create this on my own and this works superbly!
Thanks a lot Johan (and Carlo). This works absolutely great, and it's fairly easy to find your way around in with a bit of as3 knowledge.
Also a cheer for Winton DeShong who made the output data work like a proper XML.
Dudes like you guys make the world turn just a bit faster.
/pete
Nice work here, but im having problems wiht your code that i didnt had with Carlo Alducente, it connects well to the ws but when i make a request to the ws i get "Error opening URL 'wsURL'
onFault: [Fault (faultCode=ioError, faultString=Error #2032: Stream Error. URL: wsURL , faultDetail=null)]" my requests are like service.GetHighLights(returnFunction, 999);. if you could help out..
Hi there, great work with these classes. Just wondering if there was anyway to populate the faultDetail string from the Fault class. It's always null, and doesn't look like it's set anywhere?
Hey there, good stuff but for some reason the classes and example are not able for download anymore. Would you mind updating the links?
Thanks!
Great read, will save and share.
cool post, saved.
i really like your post .. i would like to bookmark your site for my future needs :)
dissertations
Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog if you don?t mind! Because I am sure my visitors will find that very useful!
It's a good article. I Have never seen such an article before. You have explained very well about yourself. Thanks for sharing this information.
custom dissertation
Post a Comment