function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
somasoma 

Apex class generated from WSDL - methods inaccessible from s-control

I generated an Apex class from a WSDL generated by a webservice I wrote that exists outside Salesforce. The resulting class has the format:

class PackageNameWebservices {
    class WebserviceSoap {
       public String endpoint_x = 'http://www.example.com/webservice.asmx';
       private String[] ns_map_type_info = new String[]{ 'http://www.example.com/', 'PackageNameWebservices' };
       ...
       public String WebserviceFunction(String arg) {...}
    }
    class SomeReturnedResponse_element {...}
    class SomeReturnedResponse {...}
}

Now, in an s-control, I'm trying to access the WebserviceFunction(), however, since it's inside of a class inside of another class (the top-level class), I rewrote the above, pulling everything inside of the WebserviceSoap class out into the top-level class, itself. I call WebserviceFunction from the s-control as follows:

sforce.apex.execute("PackageNameWebservices", "WebserviceSoap", {arg:"foo"});

When I run the s-control, I the following javascript alert pops up:

A problem with the OnClick JavaScript for this button or link was encountered:

{faultcode:'soapenv:Client', faultstring:'No operation available for request
{http://soap.sforce.com/schemas/package/PackageNameWebservice}WebserviceFunction, please check the WSDL for the service.", }

Any ideas as to what could be causing this?
SuperfellSuperfell
Only static methods marked with the WebService attribute are exposed as web services. You should leave the generated code alone and write a static wrapper for it, e.g.

global class WsWrapper {
   webservice static String WebserviceFunction(String arg) {
   PackageNameWebservices ws = new PackageNameWebservices();
  return ws.WebserviceFunction(arg);
 }
}

or alternatively you could use the ajax proxy and call your WS directly from the client without shuffling in and out of apex code.
somasoma
Thanks for the reply. It's caused me to have a few questions:

Is it necessary for an Apex class/method to be "exposed as a webservice" in order for it to be used from within an s-control?

While I understand it may be better to "leave the generated code alone" in fear of screwing something up, it seems to me that having to write a static wrapper in order to use that generated code adds an extra layer of code that is wholly unnecessary and would only serve to degrade performance. But, if I were to leave the generated code alone, would it be possible to make an sforce.apex.execute() call to a method inside of a class nested inside of a top-level class? I've tried something like sforce.apex.execute("TopLevelClass", "SubClass.methodName", {}),  but this did not work.

Thanks for pointing out the AJAX proxy method. I think I'll be using sforce.connection.remoteFunction() to handle this situation, but I do have a question in relation to this: in using this function, you prepare your own SOAP body containing the arguments you wish to transmit and you must also prepare the HTTP headers; I'm offering my external webservices through HTTPS, however, so is there anything additional I must add to the HTTP headers or does the AJAX proxy handle this for me when it sees "https" in the url argument?

Message Edited by soma on 10-13-2007 12:13 AM

SuperfellSuperfell
Yes, your apex code has to be exposed as a web service to be accessible from an s-control, the apex.execute function in the ajax toolkit can only webservice marked method. The only alternative i can think of right now is to use the executeAnonymous function, where you'd pass it a small chuck of apex code, that'll call the generated code, but getting results back from this is difficult, IIRC.

For the ajax proxy, no there's nothing special needed for HTTPS.