SOAP not working

Discuss Scalix Management Services ( formerly Scalix Admin Console )

Moderator: ScalixSupport

Barry

SOAP not working

Postby Barry » Wed Jan 23, 2008 5:30 pm

We have version 11.3.0. We have the Message Services API working fine but cannot get the SOAP API working at all. The user specified does exist (and works fine for Message Services), we've tried sending the username/password in the header and dozens of variations in the Body including several different requests but all to not avail. The response we get is Status 200 (OK) returning "Unknown Request".

If anyone could post full details of a working SOAP request we would be very grateful.

Thanks

Barry

We are sending:
Method: POST
URL: https://OurServer/caa
Content-Type: text/xml
Request Body: <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<scalix-caa:CAARequestMessage xmlns:scalix-caa="http://www.scalix.com/caa">
<ServiceType>scalix.res</ServiceType>
<FunctionName>GetActiveUsersList</FunctionName>
<Credentials id="12345">
<Identity name="test1" passwd="password"/>
</Credentials>
<ScalixServers/>
<GetActiveUsersListParameters/>
</scalix-caa:CAARequestMessage>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Barry

SOAP now working!

Postby Barry » Tue Jan 29, 2008 8:34 am

In case anyone else has the same problem: you must send a GET request to the URL to initiate the session and then subsequent POSTs will work.

We used an HTTP sniffer whilst running the Scalix Admin Console to pick up the correct format of the SOAP XML requests (which are not entirely obvious from the documentation).

PS it is not necessary to "Login" first, as authentication is sent with each message - again not obvious from the documentation.

propagandhi
Posts: 81
Joined: Wed Sep 26, 2007 8:18 am

Postby propagandhi » Tue Feb 03, 2009 1:48 am

I'm currently writing an application in C# .NET that uses the SOAP requests as well, and I am also getting the "Unkown Request" message.

All of the work I've done with PHP and SOAP is fine, somehow it just knows to do the extra POST or whatever. When I monitor the PHP scripts that I do have working, I see an initial POST, and then a subsequent post that actually fetches the response message.

I think, but am not sure that it has something to do with the transfer encoding being chunked.

If you are still around Barry, I'd love your help or to see an example of how you solved this issue!!

propagandhi
Posts: 81
Joined: Wed Sep 26, 2007 8:18 am

HTTP 1.1/302 Moved Temporarily

Postby propagandhi » Wed Feb 04, 2009 12:44 am

I'm definitely at a point where I am kicking myself in the head for my stupidity, but I'm sure at least some of you know what it's like when you look at the most complex reason for why something isn't working, when the answer is perfectly simple.

I don't believe there should be any requirement to send a GET first or anything like that, there are no oddities other than a lack of understanding on my behalf....

When I was sending SOAP requests to http://scalix.ourdomain.com/caa with C# .NET's HttpWebRequest - I was getting the HTTP 1.1/302 Moved Temporarily message, after which I would try to fetch the response from the call, and I would have the text "Unknown Request".

Quite literally the solution was to add an extra / at the end of the url: http://scalix.ourdomain.com/caa/

I believe maybe in Barry's case, they ran the initial GET and retrieved the Location or redirect headers that gave them the correct url/syntax, but of course I cannot say that for sure.

Now for those interested in making some basic soap calls to and from scalix with C# or other languages also, here is a very basic example without error handling etc etc to show roughly how to do it.

using System;
using System.Xml;
using System.Net;
using System.IO;
using System.Text;
using System.Windows.Forms;

public class ScalixSoap
{

private String UbermanagerHostname;
private String UbermanagerAPIUrl;
private String UbermanagerUsername;
private String UbermanagerPassword;
private String UbermanagerUserID;

public ScalixSoap()
{

UbermanagerHostname = "scalix.domain.com.";
UbermanagerAPIUrl = "http://scalix.domain.com/caa/";
UbermanagerUsername = "scalixadmin";
UbermanagerPassword = "password";
UbermanagerUserID = "2565";

}

//Get a string of valid xml that builds the soap envelope header
public String GetSoapHeaderXml()
{


String XMLHeader = " "
+"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ "<SOAP-ENV:Body>"
+ "<scalix-caa:CAARequestMessage xmlns:scalix-caa=\"http://www.scalix.com/caa\"> "
+ "<ServiceType>scalix.res</ServiceType>";

return XMLHeader;

}

//Returns the string of valid XML that makes up the soap envelope footer
public String GetSoapFooterXml()
{

String XMLFooter = "</scalix-caa:CAARequestMessage>"
+ "</SOAP-ENV:Body> "
+ "</SOAP-ENV:Envelope>";

return XMLFooter;

}

//Get the credentials to use when querying the API
public String GetSoapCredentialsXML()
{

String CredentialsXML = "<Credentials id=\""+this.UbermanagerUserID+"\">"
+ " <Identity name=\""+this.UbermanagerUsername+"\" passwd =\""+this.UbermanagerPassword+"\"/> "
+ "</Credentials>";

return CredentialsXML;

}

//Open a new connection to the API
public HttpWebRequest OpenSoapConnection(String Url)
{
//IMPORTANT: Turn of the Expect-100 Continue behaviour!!!
System.Net.ServicePointManager.Expect100Continue = false;

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.AllowAutoRedirect = true; //Not strictly required - it should be default

request.ContentType = "text/xml;charset=utf-8";

//It's handy to be able to look in apache or caa logs etc and search for the unique user agent our code sends.
request.UserAgent = "CSHARP-TRACE-USERAGENT/1.0";
request.Headers.Add("SOAPAction: \"1\"");

request.Method = "POST";


return request;

}

//Making a valid XML document out of the request string isn't vital, but can make sure there's no garbage in the xml we send, as it does all sorts of XML Validation
//In my case, I make the request message only the body of the scalix request I want to make, that is all the credentials and the header and footer are loaded and the RequestMessage we pass here is just the function name and parameters.

public XmlDocument BuildRequestDocument(String RequestMessage)
{

String XMLText = this.GetSoapHeaderXml() + this.GetSoapCredentialsXML() + RequestMessage + this.GetSoapFooterXml();
XmlDocument RequestDoc = new XmlDocument();
RequestDoc.LoadXml(RequestMessage);


return RequestDoc;


}

public HttpWebResponse SendSoapRequest(XmlDocument requestDocument, HttpWebRequest RequestConnection)
{

//If you want to see what you are sending
// requestDocument.Save(@"C:\RequestDocument.xml");

RequestConnection.Method = "POST";
Stream RequestStream = RequestConnection.GetRequestStream();

requestDocument.Save(RequestStream); //send the document to the POST stream

RequestStream.Close();
RequestConnection.GetResponse();
HttpWebResponse ResponseMessage;

ResponseMessage = (HttpWebResponse)RequestConnection.GetResponse();

return ResponseMessage;

}

public XmlDocument GetResponseDocument(HttpWebResponse SoapResponse)
{

//Read the response from the request, and return it as a document.
Stream ResponseStream = SoapResponse.GetResponseStream();
//Let's inspect the result

StreamReader reader = new StreamReader(ResponseStream);
String ResponseText = "";
while (!reader.EndOfStream)
{
ResponseText = ResponseText + reader.ReadLine();
}

//convert the response to an xml document
//ResponseText=System.Text.Encoding.UTF8.GetString(buffer);
MessageBox.Show(ResponseText);
SoapResponse.Close();

XmlDocument ResponseDocument = new XmlDocument();
ResponseDocument.LoadXml(ResponseText);

return ResponseDocument;

}


}


You would call the above class in the following way:

ScalixSoap SoapClient = new ScalixSoap();

String UbermanagerQueryServer = "scalix.domain.com"; //or write a method to get the ubermanager API URL out of the class above etc etc
String ServerList = "<ScalixServers><Host>scalix.domain.com</Host></ScalixServers>";
String FunctionName = "<FunctionName>GetServersList</FunctionName>";
String FunctionOptions = ""; //eg maxrows="200"
String FunctionParameters = "<filters><typefilter value=\"normal\"/></filters>";

String SoapServerList = SoapClient.GetServerList("scalix.domain.com");
String RequestMessage = ServerList + FunctionName+ FunctionParameters; //That's the body of the request

XmlDocument RequestDoc = SoapClient.BuildRequestDocument(RequestMessage); //Gives us a validated Soap XML Doc

//open soap connection
HttpWebRequest SoapConnection = SoapClient.OpenSoapConnection(UbermanagerQueryServer);

//Send the request
HttpWebResponse Response = SoapClient.SendSoapRequest(RequestDoc,SoapConnection);

//Get the response
XmlDocument ResponseDoc = SoapClient.GetResponseDocument(Response);

//Now you would save or process the document however you like

XmlDocument.Save(@"C:\ResponseDocument");




I'd be more than happy to elaborate if anyone needs it, I've got a much bigger code base written now than that, but it just occurred to me how very infrequently people come back to forums with answers after they solve their problems.

I only had 5 spare minutes here to knock this up, and I'm not at my development machine and don't have visual studio with me so excuse any mistakes, I think the basic idea is shown here, but I haven't run this code or anything, so please point out any errors I made!


Cheers.
Last edited by propagandhi on Sun Nov 22, 2009 7:47 pm, edited 1 time in total.

alefront

Re: HTTP 1.1/302 Moved Temporarily

Postby alefront » Thu May 28, 2009 12:10 pm

Hi, your code is greate!!
Can you help to use it from visual basic?.
Is there any possible to write in visual basic?
Thank for all.
Alejandro
Uruguay

propagandhi
Posts: 81
Joined: Wed Sep 26, 2007 8:18 am

Re: HTTP 1.1/302 Moved Temporarily

Postby propagandhi » Thu May 28, 2009 5:25 pm

alefront wrote:Hi, your code is greate!!
Can you help to use it from visual basic?.
Is there any possible to write in visual basic?
Thank for all.
Alejandro
Uruguay



It definitely is possible to write it in visual basic, though I don't have time to redo the examples for you in vb .net just yet. However, I am more than happy to help you with your code if you paste what you have already and give me an idea of where you are having troubles.

alefront

Re: SOAP not working

Postby alefront » Wed Jul 01, 2009 9:27 am

Hi, if you have a little time , i ask you to see this code that return the error:

Run-time error '-2147352567 (80020009)';
WSDLReader:XML Parser failed at linenubmer 1, lineposition 1, reason is:Incorrect document syntax. HRESULT=0x1:Función incorrecta.....


The visual basic code send is:
Set soapclient = CreateObject("MSSOAP.SoapClient30")
soapclient.ClientProperty("ServerHTTPRequest") = True
Call soapclient.MSSoapInit(AV8Cconws)
soapclient.Execute (AV13Resxml)


Where the var AV13Resxml contain:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<scalix-caa:CAARequestMessage xmlns:scalix-caa="http://192.168.0.249/caa">
<ServiceType>scalix.res</ServiceType>
<Credentials id="2565"/>
<Identity name="admin" passwd="xxx"/>
</Credentials>
<FunctionName>FunctionName</FunctionName>
<ScalixServers>
<Host>alefront@xxx.com.uy</Host>
<Host>xxxy.com.uy</Host>
</ScalixServers>
<FunctionNameParameters>
</FunctionNameParameters>
</CAARequestMessage>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>




Return to “Scalix Management Services”



Who is online

Users browsing this forum: No registered users and 1 guest