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
zirosziros 

Apex class: calling webservice with args as xml

Hello, I have the next simple scenario:
 
scontrol which calls an apex class that calls ASP.NET webservice as the following :
(all is working fine)
 
global class WSIchlusSalesForceHelper
{
    global class ContactIchlus
    {
            webservice String ContactRole;
            webservice String BirthDate;
            webservice String arg1;
            webservice String arg2;
            webservice String arg3;
            webservice String arg4;
            ...
            ...
    }
 
    WebService static string test1(ContactIchlus data)
    {
        WSIchlusSalesForce.ServiceIchlusSoap soap = new WSIchlusSalesForce.ServiceIchlusSoap();
        return soap.IchlusProtocol(data.BirthDate);
     }
}
 
My question is,
In the inner class ContactIchlus which will have at least 20 variables or more, that I need to pass to the webservice...
I can't just pass the variable data...
 
Is there a simple way to convert that inner class to XML and pass it to the webservice ?
or I will have to concat string and build the xml myself ?
or maybe I will have to define 20 args to the webservice
 
TIA (it's my first webservice)
David VPDavid VP

Construct an object type on the .NET side of things that will have all these properties.
Pass the web service an argument of that object type.


Take your new WSDL and generate the Apex classes and you should see an equivalent (inner) class being generated there.

Just create an instance of it, set all the variables and pass that to your web service.


Hope this helps,


David
zirosziros
David thank you very much for the quick answer, I'll start applying this approach , hope that it will be ok
will post my results (problems/success)
 
Thanks again
zirosziros

David / Others

I do have a problem here , hope you can help

I created a class in asp.net and it generate as you said an inner class within the generated apex class from wsdl

so now this is the part within the generated apex class:

public class ContactIchlus {
        public DateTime BirthDate;
        public String ContactRole;
        public Integer DistrictCode;
        private String[] BirthDate_type_info = new String[]{'BirthDate','http://www.w3.org/2001/XMLSchema','dateTime','1','1','false'};
        private String[] ContactRole_type_info = new String[]{'ContactRole','http://www.w3.org/2001/XMLSchema','string','0','1','false'};
        private String[] DistrictCode_type_info = new String[]{'DistrictCode','http://www.w3.org/2001/XMLSchema','int','1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://tempuri.org/','true'};
        private String[] field_order_type_info = new String[]{'BirthDate','ContactRole','DistrictCode'};
    }

and this is my apex class which uses  it

global class WSIchlusSalesForceHelper
{
    WebService static string test1(WSIchlusSalesForce.ContactIchlus data)
    {
        WSIchlusSalesForce.ServiceIchlusSoap soap = new WSIchlusSalesForce.ServiceIchlusSoap();
        
        return soap.IchlusProtocol(data.BirthDate);
      }
}

The error I'm getting on my class is

Error: Compile Error: Argument type of global method must also be global: WSIchlusSalesForce.ContactIchlus at line 9 column 30

becuase my class calls a webservice it needs the Global declaration... but in the generated class from wsdl the inner class is not global... how to overcome this....

TIA

David VPDavid VP

It's only when your own class needs to be exposed as a webservice that it needs to be global. Not when you're calling a webservice.

Your not creating a webservice on Salesforce.com just for calling another .NET webservice right ?


David

zirosziros
you right I just need to call webservice, I tried to replace the Globl keyword  in my class to public
but than this error occured...
 
Error: Compile Error: Webservice methods must be contained in a global class at line 9 column 30
 
which means that if I calling webservice my class should be global  ?
 
TIA
zirosziros
It seems that the problem of mine is with the scontrol to apex class.
 
if I want to call an apex class (which is not exposed as webservice)
from scontrol how can I achive that
 
as for now I did that call
 
  var data = new sforce.Xml("WSIchlusSalesForce.ContactIchlus");
  data.BirthDate = '{!Contact.Birthdate}';
  var result = sforce.apex.execute("WSIchlusSalesForceHelper" ,"test1", {sd:data});
 
and the apex class had the webservice key word in front of the static function , but I removed the webservice keyword... so how can I call that class method from scontrol without sforce.execute ?
 
TIA
David VPDavid VP
Error: Compile Error: Webservice methods must be contained in a global class at line 9 column 30


That's because you put the 'Webservice' keyword in your method. You don't need to do that.

The Webservice keyword is when you want to expose your Apex method as a webservice. If I understand correctly, that's not what you want to do. You just want to *call* an external .NET webservice right ?

The .NET webservice is the 'server' and the Apex class needs to be the 'client'. Can you confirm that ?



David






DpalDpal

I am not much help here since I am having the exact same problem (different wsdl - but same arrangement).

I don't know if the OP chose the webservice keyword, but I choose it because I am reading from the cookbook example "Sending messages from Apex" and thats the way the example is setup.  Unfortunately it doesn't work for my wsdl either.

If I understand the example in the book right, they are suggesting you create the webservice that calls the webservice so it can be used in any S-Control through the ajax toolkit with apex.execute.

Are you saying skip this and put it directly in the S-Control?

David VPDavid VP

OK, it just dawned on me (that's the difference between late at night and early morning : sleeping always reboots my brain :smileywink: ) : you're coming from an S-Control ... that's why you went the Apex web service route ...
So it's : S-Control -> Apex Webservice -> .NET Webservice right ?

Couldn't you just use a VF page + controller to do what you're doing ? ... today VF is more or less favored over using S-Controls (and if you ask me, it's much easier to do too).

Anyway : You've got this far already so you might want to try this first : in the wsdl2apex generated class, modify the access modifiers from 'public' to 'global' for your inner classes/methods... that will bring this class and it's members in the global scope and might help you get rid of the 'Argument type of global method must also be global: ' message.


Hang in there, you'll get it working !


David



zirosziros
Lol
Exactly this is the current route - S-Control -> Apex Webservice -> .NET Webservice
 
Dpal thanks also for clearing this :smileyhappy:
 
I end up last night doing what you suggested with changing public to global in the generated wsdl,
and compilation went through, just have to check it now for completion.
I know VF page is favoured over s-control... but a little bit new to it...
but lets say ... If I need a button from contacts to activate my webservice, and instead of custom control I'll use VF page, isn't the replacement of contacts with VF page will make Contacts without the abilities to customize it ?
Will be happy to use the VF page approache
any help will be appriciated
 
DpalDpal
I'd love to hear more about the VF page too.  When to use what is a bit confusing in Salesforce.  I knew I wanted to make a page that consumed a web service (the preference was just to send xml to the xsd, but the examples I found seemed to prefer the wsld) and the only samples I found were for the S-control.
 
I got it working last night too - by making my own global class that incorporated the private class.  But doing that for every class (its a big wsdl) was daunting.
 
I tried do a find and replace on the original and replacing every public class with global class last night which didnt work - but then I put the result in a new class so maybe there were references not lining up.  I'll look at it again later, late for meetings. :)