Using LoadVars sendAndLoad instead of WebService when calling web services with Flash ActionScript

by filip 14. August 2008 17:53

I've ran into issues using the WebService object in Flash.  The thing is incredibly buggy.  In certain cases, it works just fine, but in other cases, it flat out does not work. In my last case, the web service loaded perfectly fine (onLoad was called), but the PendingCall would not return anything.  The onFault method was never called after I invoked my web service call, but the web service never returned either.  Examining the outgoing messages from Flash (using HTTP headers in Firefox) revealed that Flash was never even attempting to call the web service.  Flash did correctly acquire the crossdomain.xml file (which allowed access from all domains), and it did load the WSDL.  But, for whatever reason, it did not call the web method like it was supposed to.

Well, after a few hours or attempging to make this work, I gave up with the WebService object.  Instead, I went to the LoadVars object, something I'm more confident in than the WebService class, simply due to the fact that it has been around much longer and has had more attention from the Adobe / Macromedia team.

Using the WebService object, my code looked like the following:

var _wsdl:String = "http://www.bloodforge.com/webservice.asmx?WSDL"; // <- this is fake for the purpose of this blog 
var MailService:WebService = new WebService(_wsdl);
MailService.onLoad = function()
{
  var MailServiceResult:PendingCall = MailService.MyMethod("my parameters");
  MailServiceResult.onFault = function(fault)
  {
    trace("it never gets here even though it fails!");
  }
  MailServiceResult.onResult = function(result)
  {
    trace("it never got here either!");
  }
}

The above was replaced with the code below, and it works perfectly fine:

var result_lv:LoadVars = new LoadVars();
result_lv.onData = function(responseStr:String)
{
  if(responseStr == undefined)
  {
    trace("Error occurred!");
  }
  else
  {
    trace("Success... parse my data below...");
  }
}
var send_lv:LoadVars = new LoadVars();
send_lv.myWebServiceParam1 = "param 1";
send_lv.myWebServiceParam2 = "param 2";
send_lv.sendAndLoad("http://www.bloodforge.com/webservice.asmx/MyMethod", result_lv, "POST");

 
Oh, and make sure that if you do this with your web service, that you have the following line in your web.config file.  Otherwise, you won't be able to access it using these methods (you should be familiar w/ it anyways if you use Ajax to call web services).

<webServices>
  <
protocols
>
    <
add name="HttpGet"
/>
    <
add name="HttpPost"
/>
  </
protocols
>
</
webServices>

Tags: , ,

Web Development

Comments (1) -

Andreea
Andreea Romania
7/30/2010 3:49:47 AM #

I bumped into the same problem, but I managed to find a workaround..  although  I totally support your loadVars approach. Maybe this will be helpful though:

import mx.services.*;
var webService;

function improvedDelegate(target:Object, handler:Function):Function {
  var func = function() {
    var context:Function = arguments.callee;
    var args:Array = arguments.concat(context.initArgs);
    return context.handler.apply(context.target, args);
  }
  func.target = target;
  func.handler = handler;
  func.initArgs = arguments.slice(2);
  return func;
}

function webServiceConnect():Void {
  webService.suppressInvalidCalls = true;
  webService = new WebService("www.flash-mx.com/.../problems.cfc?WSDL";);
  webService.onLoad = this.improvedDelegate(this, webServiceLoad);
  webService.onFault = this.improvedDelegate(this, webServiceFault);
}
function webServiceFault():Void {
  trace("web service connect onFault");
}
function webServiceLoad():Void {
  trace("web service connect onLoad");
}

function loginCall(){
  
  trace("inside login call");
  
  var pc = webService.getProblems();
  pc.onResult = this.improvedDelegate(this, pendingCallResult);
  pc.onFault = this.improvedDelegate(this, pendingCallFault);
  
}

function pendingCallResult(result):Void {
  trace("pending call Result: " + result);
}

function pendingCallFault(fault:SOAPFault):Void {
  trace("pending call Fault " + fault.faultstring);
}

webServiceConnect();
loginCall();

Reply

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


About Filip Stanek

Death Note Pic I'm a developer at ACG in Cincinnati, OH. I like ASP.NET, Flash, and other web technologies, & enjoy playing chess, video games, etc.

Currently playing:
- StarCraft IIE-mail me Send mail

RecentComments

Comment RSS

Month List