I followed the advice provided here and it worked like a charm. Right now, I'm connecting to the server and calling a method named GetFunctionalityTest. The only input to it is a string, which can be seen in the GetFunctionalityTest.m file. So far so good.
Then I attempted to call the real service named GetSections whose signature according to the file GetSections.m is as follows.
function GetSectionsResult = GetSections(obj,auth)
% GetSections(obj,auth)
% Input: auth = (Authorize)
% Output: GetSectionsResult = (ArrayOfString)
values = { auth, };
names = { 'auth', };
types = { '{WSPro.HostingWebservice}Authorize', };
soapMessage = createSoapMessage( ...
'WSPro.HostingWebservice', ...
'GetSections', values,names,types,'document');
response = callSoapService( obj.endpoint, ...
'WSPro.HostingWebservice/GetSections', soapMessage);
GetSectionsResult = parseSoapResponse(response);
The definition provided by the server is as follows.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi=...>
<soap:Body>
<GetSections xmlns="WSPro.HostingWebservice">
<auth>
<uid>string</uid>
<pw>string</pw>
</auth>
</GetSections>
</soap:Body>
</soap:Envelope>
My problem is that I can't specify the authorization syntax-wise. As far I understand, it's supposed to consist of two strings somehow but I haven't get it to work. I've tried to compound those as follows.
myAuthorization = ['user', 'pass'];
myAuthorization = {'user', 'pass'};
myAuthorization = ['user' 'pass'];
myAuthorization = {'user' 'pass'};
Nothing helped. I just got a bunch of errors.
Error using callSoapService (line 147)
Unspecified Fault: SOAP Fault: Server was unable to process request.
---> The parameterized query
'(#uid nvarchar(99)) SELECT PassW FROM UserData WHERE UserId = #' expects the parameter '#uid', which was not supplied.
I've browsed all the files automatically created for me and there's no definition of Authorize not ArrayOfString. I'm guessing it's something that the server defines, since I get no hits on those in MatLab documentation.
How can I specify the credentials for authorization?
Where can I look up how MatLab maps Authorization?
As noted above:
The SOAP Authentication happens through SOAP Header and not SOAP Body.This link might give you an idea of how SOAP XML should look in case of authentication :
Web service soap header authentication
Related
From Elixir, I am trying to call a SOAP Web Service with detergentex, which is a wrapper around the Erlang library detergent.
I can call the SOAP Web Service in the example on the detergent home page with no problems: http://www.webservicex.net/convertVolume.asmx?WSDL
Parameters:
wsdl_url = "http://www.webservicex.net/convertVolume.asmx?WSDL"
action = "ChangeVolumeUnit"
parameters = ["100","dry","centiliter"]
However when trying to call an Axis2 Java SOAP Web Service I am having some problems. Example: http://www.thomas-bayer.com/axis2/services/BLZService?wsdl
When calling "getBank" in the following way
wsdl_url = "http://www.thomas-bayer.com/axis2/services/BLZService?wsdl"
action = "getBank"
parameters = ["abc"]
wsdl = Detergentex.init_model(wsdl_url)
res = Detergentex.call(wsdl, action, parameters)
I get the following error message:
{:error, 'Struct doesn\'t match model: recordtype not expected: p:getBank'}
with the following stack trace
src/erlsom_write.erl:357: :erlsom_write.findAlternative/4
src/erlsom_write.erl:258: :erlsom_write.processSubType/5
src/erlsom_write.erl:241: :erlsom_write.processElementValues/7
src/erlsom_write.erl:132: :erlsom_write.struct2xml/6
src/erlsom_write.erl:323: :erlsom_write.processAlternativeValue/8
src/erlsom_write.erl:241: :erlsom_write.processElementValues/7
src/erlsom_write.erl:116: :erlsom_write.struct2xml/6
src/erlsom_write.erl:323: :erlsom_write.processAlternativeValue/8
src/erlsom_write.erl:241: :erlsom_write.processElementValues/7
src/erlsom_write.erl:45: :erlsom_write.write/2
src/detergent.erl:211: :detergent.call_attach/8
Any suggestions as to what I'm doing wrong?
According to the implementation a prefix is added on the init_model.
def init_model(wsdl_url, prefix \\ 'p') do
Detergentex.Client.init_model(wsdl_url, prefix)
end
I would suggest to add an empty prefix.
SUM: I ended up having to form the XML manually. I also had to create an Operation and use its send(); method rather than just doing something like WebService.MyServiceFunction(); - not sure why that was the case.
I send off the request as follows:
var xm:XML =
<SetPropertiesForCurrentUser xmlns="http://asp.net/ApplicationServices/v200">
<values xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:KeyValueOfstringanyType>
<d4p1:Key>{obj.Key}</d4p1:Key>
<d4p1:Value xmlns:d6p1="http://www.w3.org/2001/XMLSchema" i:type="d6p1:string">{obj.Value}</d4p1:Value>
</d4p1:KeyValueOfstringanyType>
</values>
</SetPropertiesForCurrentUser>;
var profileService:WebService = new WebService();
profileService.useProxy = false;
profileService.loadWSDL(url);
var o:Operation = profileService.SetPropertiesForCurrentUser;
o.send(xm);
Here’s my scenario:
I have ASP.NET web services to handle authentication, user roles, and user profiles (default ASP.NET AuthenticationService, RoleService, and ProfileService, to be exact).
So from my Flex web app, I am able to successfully call the ASP.NET service. For example, something like this works fine:
var profileService:WebService = new WebService();
profileService.useProxy = false;
profileService.GetAllPropertiesForCurrentUser.addEventListener("result",getAllPropertiesForCurrentUser_EventHandler);
profileService.addEventListener("fault",getAllPropertiesForCurrentUserFault_EventHandler);
profileService.loadWSDL(url);
profileService.GetAllPropertiesForCurrentUser();
I run into trouble when I need to pass a Dictionary object to another function on the service (SetPropertiesForCurrentUser). The .NET service asks for this type of value:
System.Collections.Generic.IDictionary(Of String, Object)
Here are the two pertinent entries from the web.config entry from my ASP.NET service:
<properties>
<clear/>
<add name="coordinateFormat" />
</properties>
...
<profileService enabled="true"
readAccessProperties="coordinateFormat"
writeAccessProperties="coordinateFormat"/>
So after putting together a SOAP request from a Silverlight app (which works as expected) I’ve narrowed it down to a difference in the XML request sent to the SOAP handler:
From Flex:
<tns:Value>DMS</tns:Value>
From Silverlight:
<d4p1:Value xmlns:d6p1="http://www.w3.org/2001/XMLSchema" i:type="d6p1:string">DMS</d4p1:Value>
If I take the request generated by Flex, catch it with Fiddler, modify that one line to include the “type” namespace – it works.
Anyone have an idea how I can get that namespace onto my variable that is passed to the SOAP handler from Actionscript? Here is my code for sending off that SetPropertiesForCurrentUser function:
var obj:Object = {};
obj["Key"] = "coordinateFormat";
obj["Value"] = DMS;
var profileService:WebService = new WebService();
profileService.useProxy = false;
profileService.SetPropertiesForCurrentUser.addEventListener("result",setPropertiesForCurrentUser_EventHandler);
profileService.addEventListener("fault",setPropertiesForCurrentUserFault_EventHandler);
profileService.loadWSDL(url);
profileService.SetPropertiesForCurrentUser(new ArrayCollection([obj]),false);
Thanks,
Josh
The default SOAPEncoder that is used is some what limited in its capabilities (like not including the type attribute you mentioned above). Luckily, there is a way to control that by writing your own encoder.
see this link at adobe (read part about using custom web service serialization) Link on Adobe's Site
I'm currently trying to call Amazon Product Retail Web Service in Salesforce.
As I mentioned in
Getting WSDL parse error while generating Apex code from WSDL in Salesforce
I was initially unable to generate apex stub class, but I followed the method suggested by #Ballinger and created apex class. I wrote an apex class to use that stub and to set request parameters. The class i wrote is as follows
public class AmazonProductStubNew
{
public static void getResults()
{
System.Debug(' getResults start ');
AmazonWS.AWSECommerceServicePortUS stub = new AmazonWS.AWSECommerceServicePortUS();
stub.inputHttpHeaders_x = new Map<String,String>();
stub.inputHttpHeaders_x.put('AWSAccessKeyId','MyAmazonAWSAccessKeyId');
stub.inputHttpHeaders_x.put('Timestamp','2012-11-28T12:11:30Z');
stub.inputHttpHeaders_x.put('Signature','Encrypted Secret Code');
String MarketplaceDomain = '';
String AWSAccessKeyId = 'MyAmazonAWSAccessKeyId';
String AssociateTag = '';
String XMLEscaping = '';
String Validate = '';
AmazonWS.ItemSearchRequest Shared = new AmazonWS.ItemSearchRequest();
Shared.SearchIndex = 'DVD';
AmazonWS.ItemSearchRequest[] Request = new AmazonWS.ItemSearchRequest[1];
Request[0] = new AmazonWS.ItemSearchRequest();
Request[0].Title = 'Inception';
AmazonWS.ItemSearchResponse_element response = stub.ItemSearch(MarketplaceDomain,AWSAccessKeyId,AssociateTag,XMLEscaping,Validate,Shared,Request);
AmazonWS.Items_element[] localItems = response.Items;
System.Debug(localItems[0].TotalResults);
}
}
Even though I've added HTTP headers to stub, I'm not getting it in XML Request message
XML Request is as follows
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header />
<env:Body>
<ItemSearch xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
<MarketplaceDomain>
</MarketplaceDomain>
<AWSAccessKeyId>MyAWSAccessKeyId</AWSAccessKeyId>
<AssociateTag></AssociateTag>
<XMLEscaping></XMLEscaping>
<Validate></Validate>
<Shared><SearchIndex>DVD</SearchIndex></Shared>
<Request><Title>Inception</Title>
</Request></ItemSearch>
</env:Body></env:Envelope>
Since headers are not there in SOAP Request, There is a SOAP fault asking for Signature from Amazon Server.
As you can see, I'm new to Salesforce Apex. I followed the steps in
http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_web_services_wsdl2apex.htm#http_header_support
to set the headers.
Any idea on why the header isn't getting added?
P.S I added headers manually and tried in SOAP UI, I'm getting proper response.
Thanks :)
I think you're using wrong functions :) (question is indeed confusing).
SOAP (or generally HTTP) communication consists of sending headers and actual message (payload if you like). Headers are short text thingies, message is often a giant XML.
Your code is setting HTTP headers (which are used in web communication to authenticate, provide info about your browser, preferred languages, set cookies, return status codes like 404 page not found...) Please don't be offended with the "for dummies" but I realize the wikipedia article is a bit too much, this might be simpler: http://net.tutsplus.com/tutorials/other/http-headers-for-dummies/
And what I suspect Amazon's webservice wants is just some fields inside the <env:Header>...</env:Header> tag? Just check the generated apex code for existence of subclass called "Header" (you can also search for the variable names like "Signature". This is going to be a total wild guess but I think you'll have to write something like that:
AmazonWS.AWSECommerceServicePortUS stub = new AmazonWS.AWSECommerceServicePortUS();
AmazonWS.Header h = new AmazonWS.Header();
h.AWSAccessKeyId = 'MyAmazonAWSAccessKeyId';
h.Timestamp = '2012-11-28T12:11:30Z';
h.Signature = 'Encrypted Secret Code';
stub.Header = h; // plug it into the request
// create and plug other required tags
AmazonWS.ItemSearchRequest Shared = new AmazonWS.ItemSearchRequest();
Shared.SearchIndex = 'DVD';
AmazonWS.ItemSearchRequest[] Request = new AmazonWS.ItemSearchRequest[1];
Request[0] = new AmazonWS.ItemSearchRequest();
Request[0].Title = 'Inception';
// ...
Now, to make it more confusing you might still have to use a HTTP header, there's a special one called SOAPAction. But generally speaking I believe you're after placing your data in the XML, not in http headers.
Funny enough, I've downloaded the Java example from http://aws.amazon.com/code/Product-Advertising-API/2478 and if I read it correctly they're passing the signature in the URL (endpoint), not in the XML. Probably because it's a REST GET method (if you can access that API it could save you a lot of hair pulled, SOAP is clunky).
I am making a web service call (in .Net 3.5). I want the Soap request to have namespace prefixes for the tags (the third-party web service needs them).
Current request:
<soap:Body> <GetBanksList xmlns="urn:QueryGroup"> ...
Desired request:
<soap:Body> <pfx:GetBanksList xmlns:pfx ="urn:QueryGroup"> ...
It seems I should use this attribute:
[XmlElementAttribute(Form = XmlSchemaForm.Unqualified)]
and specify my prefix, probably like this:
XmlSerializerNamespaces _namespaces = new XmlSerializerNamespaces(
new[] { new XmlQualifiedName("pfx", NS1) } );
What I can't find is where to put the attribute (I tried with the input params in Reference.cs) and where to specify the prefix!
Thanks for any help.
I'm trying to dynamically send a SOAP request to different webservices. Each webservice has its own ID, so I just basically have to change the ID of the webservice in the URL, E.G.:
http://mywebservice.com/ID/servicedosomething
Anyway, I don't know how to do this manually. I can't reference the services because I would have to add a lot of web references into the app, which doesn't seem very good to do.
Anyway, I just want to know how to construct the SOAP request, send it, and get the result from the service. Btw, I've checked other solutions to similar questions and none worked for me, might be the WP7 framework or something.
Thanks!
From my experience, it is very easy to design and build Windows Phone applications with RESTful web services. In a situation where you only have SOAP XML web services to work with, you will need to do some work within the application to prepare the request, send it and parse the response.
You can store the webservice URL as a string "template" like so -
string wsUrlTemplate = "http://mywebservice.com/{0}/servicedosomething";
When you are about to issue a request, just format the string -
string wsUrl = string.Format(wsUrlTemplate, webServiceID);
If you have the SOAP XML request format, then store it as a template. When you need to issue the request, replace the placeholders with the actual values and send the request (with a POST option, if thats what the web services expect). A typical SOAP XML request template may look like -
string xmlRequestTemplate = "
<?xml version="1.0" encoding="utf-8" ?>
<Customer>
<CustomerID>{0}</Customer>
</Customer>"
To prepare the request XML, you adopt the same approach as above - string format the xmlRequestTemplate and add the CustomerID. To issue the request, use HttpWebRequest to asynchronously issue the request and in the response handler, parse the XML response.
var request = HttpWebRequest.Create(wsUrl);
var result = (IAsyncResult)request.BeginGetResponse(ResponseCallback, request);
private void ResponseCallback(IAsyncResult result)
{
var request = (HttpWebRequest)result.AsyncState;
var response = request.EndGetResponse(result);
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
var contents = reader.ReadToEnd();
// Parse the XML response
}
}
Hope this gives you some ideas to proceed.
indyfromoz