I am trying use a web service in a C# ASP.Net Web Application. The service is built in PHP and is located on some remote server not under my control so I cant modify it to add
As referenced that - you will have to hand code your "proxy" for this web service.
One example of manually making a web service call - you may have to tweak the method some.
private string MakeWebServiceCall(string methodName, string requestXmlString)
{
WebRequest webRequest = WebRequest.Create("https://subreg.forpsi.com/robot2/subreg_command.php");
HttpWebRequest httpRequest = (HttpWebRequest)webRequest;
httpRequest.Method = "POST";
httpRequest.ContentType = "text/xml";
httpRequest.Headers.Add("SOAPAction: https://subreg.forpsi.com/robot2/subreg_command.php/" + methodName);
Stream requestStream = httpRequest.GetRequestStream();
//Create Stream and Complete Request
StreamWriter streamWriter = new StreamWriter(requestStream);
streamWriter.Write(String.Format(this.GetSoapString(), requestXmlString));
streamWriter.Close();
//Get the Response
WebResponse webResponse = httpRequest.GetResponse();
Stream responseStream = webResponse.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream);
//Read the response into an xml document
System.Xml.XmlDocument soapResonseXMLDocument = new System.Xml.XmlDocument();
soapResonseXMLDocument.LoadXml(streamReader.ReadToEnd());
//return only the xml representing the response details (inner request)
return soapResonseXMLDocument.GetElementsByTagName(methodName + "Result")[0].InnerXml;
}
I would recommend creating xsd's which can be used to generate objects (using xsd.exe) and then you can serialized/deserialize responses and requests to actually objects.
EDIT: GetSoapString() method
private string GetSoapString()
{
StringBuilder soapRequest = new StringBuilder("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
soapRequest.Append(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ");
soapRequest.Append("xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body>");
soapRequest.Append("{0}");
soapRequest.Append("</soap:Body></soap:Envelope>");
return soapRequest.ToString();
}
For Steve's Reference
Call one looks like:
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<get_contact>
<id>123</id>
</get_contact>
</soap:Body>
</soap:Envelope>
Response:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:t3" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:get_contactResponse>
<get_contactReturn xsi:type="xsd:boolean">false</get_contactReturn>
</ns1:get_contactResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Edit: Previously i got a 500 Internal server error because my soap string was not correctly formatted. I ananlyzed the xml being returned from the web service and built my soap string message by look at xml. Finally i got over the problem with help from Dan ^ & some bit of research over the internet. Thanks Dan.
I got over the 500 server error. Now i am able to get a response of login failure atleast...
public String MyWebServiceCall()
{
string strSoapMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tns=\"http://www.artwork-systems.com/webway/sessions\" xmlns:types=\"http://www.artwork-systems.com/webway/sessions/encodedTypes\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
+ " <soap:Body soap:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
+ " <tns:Login>"
+ " <login xsi:type=\"xsd:string\">Support@foo.net</login>"
+ " <auth xsi:type=\"xsd:string\">bar</auth>"
+ " </tns:Login>"
+ " </soap:Body>"
+ "</soap:Envelope>";
HttpWebRequest req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(@"https://subreg.forpsi.com/robot2/subreg_command.php/"));
req.ContentType = "text/xml; charset=UTF-8";
req.Method = "POST";
req.Accept = "text/xml";
req.Headers.Add("SOAPAction", @"https://subreg.forpsi.com/robot2/subreg_command.php/");
req.ProtocolVersion = HttpVersion.Version11;
req.Credentials = CredentialCache.DefaultCredentials;
//req.Credentials = new NetworkCredential("Support@foo.net", "bar");
StreamWriter stm = new StreamWriter(req.GetRequestStream(), Encoding.ASCII);
stm.Write(strSoapMessage);
stm.Flush();
stm.Close();
HttpWebResponse wr = (HttpWebResponse)req.GetResponse();
StreamReader srd = new StreamReader(wr.GetResponseStream());
string resulXmlFromWebService = srd.ReadToEnd();
return resulXmlFromWebService;
}
Now the next problem is to pass the correct credentials and process the response to do other stuff...
btw, here was the response....
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:t3" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:loginResponse><loginReturn xsi:type="xsd:boolean">false</loginReturn></ns1:loginResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
Edit: The value false is Ok as i am sending in the wrong credentials. i call other functions of the web service in a similar fashion and was able to call all functions of the web service and retrieve the corresponding return values and then perform other processing.
Thanks all who helped contributing to solve the problem.
Regards
"webservice" is a very generic term. Some types of webservice may implement a WSDL - but its not a requirement. IIRC a SOAP interface is required to provide a WSDL, and both nuSOAP and the PHP SOAP extension support WSDL. So it looks like the remote end hasn't been implemented properly.