¿Cómo acceder a un servicio web PHP desde ASP.Net?

Estoy intentando usar un servicio web en una aplicación web C # ASP.Net. El servicio está construido en PHP y está ubicado en algún servidor remoto que no está bajo mi control, así que no puedo modificarlo para agregar metadatos o algo más.

Cuando uso la opción “Agregar referencia web” en Visual Studio 2008, recibo el siguiente error:

El documento HTML no contiene información de descubrimiento del servicio web.

al intentar agregar el siguiente servicio web.

https://subreg.forpsi.com/robot2/subreg_command.php?wsdl

Las funciones del servicio web están expuestas y se muestran en Visual Studio 2008. Sin embargo, no pude agregar la referencia para utilizarla en la aplicación ASP.Net.

t3Service “Descripción

Métodos __construct ()

crear contacto ( )

get_contact ()

get_domain_info ()

get_last_error_code ()

get_last_error_msg ()

get_NSSET ()

get_owner_mail ()

iniciar sesión ( )

register_domain ()

register_domain_with_admin_contacts ()

renew_domain ()

request_sendmail ()

send_auth_info ()

transfer_domain ()

  1. También probé el método wsdl.exe recuperando el xml y copiándolo en un archivo wsdl y generando una clase de proxy. Pero la salida wsdl contiene advertencias y la clase de proxy generada omite las funciones expuestas y genera algo como esto:

    // CODEGEN: Se ignoró el enlace de la operación ‘create_contact’ desde el espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: Se ignoró el enlace de operación ‘get_contact’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró el enlace de operación ‘get_domain_info’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: Se ignoró el enlace de operación ‘get_last_error_code’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró el enlace de operación ‘get_last_error_msg’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: Se ignoró el enlace de operación ‘get_NSSET’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró el enlace de operación ‘get_owner_mail’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró el enlace de la operación ‘send_auth_info’ desde el espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró el enlace de operación ‘transfer_domain’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró el enlace de la operación ‘request_sendmail’ desde el espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró la operación que vincula ‘login’ desde el espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: Se ignoró el enlace de la operación ‘domain_registro’ del espacio de nombres ‘urna: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: Se ignoró la operación vinculante ‘register_domain_with_admin_contacts’ desde el espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo. // CODEGEN: se ignoró la operación vinculante ‘renew_domain’ del espacio de nombres ‘urn: t3’. Cada parte del mensaje en un mensaje use = encoded debe especificar un tipo.

Editar:

Intenté esta pieza de código para mi clase codificada a mano.

public String makeWebRequest(String methodName) { // Create the web request HttpWebRequest request = WebRequest.Create("https://subreg.forpsi.com/robot2/subreg_command.php/") as HttpWebRequest; // Add authentication to request request.Credentials = new NetworkCredential("[email protected]", "bar"); request.Method = "POST"; request.ContentType = "text/xml"; request.Headers.Add("SOAPAction: https://subreg.forpsi.com/robot2/subreg_command.php/" + methodName); // Get response using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { // Get the response stream StreamReader reader = new StreamReader(response.GetResponseStream()); // Console application output //Console.WriteLine(reader.ReadToEnd()); return reader.ReadToEnd(); } } 

Pero cuando trato de obtener respuesta, entonces vuelve

El servidor remoto devolvió un error: (500) Error interno del servidor.

Como se menciona, tendrá que codificar manualmente su “proxy” para este servicio web.

Un ejemplo de realizar manualmente una llamada al servicio web: es posible que tenga que modificar un poco el método.

 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; } 

Recomendaría crear xsd que se pueda usar para generar objetos (usando xsd.exe) y luego podrá serializar / deserializar respuestas y solicitudes a objetos en realidad.

EDIT: método GetSoapString ()

 private string GetSoapString() { StringBuilder soapRequest = new StringBuilder(""); soapRequest.Append("{0}"); soapRequest.Append(""); return soapRequest.ToString(); } 

Para la referencia de Steve

Llamar a uno se ve así:

    123    

Respuesta:

    false    

“webservice” es un término muy genérico. Algunos tipos de servicios web pueden implementar un WSDL, pero no es un requisito. IIRC requiere una interfaz SOAP para proporcionar un WSDL, y tanto nuSOAP como la extensión SOAP de PHP son compatibles con WSDL. Por lo tanto, parece que el extremo remoto no se ha implementado correctamente.

Editar: Anteriormente recibí un error interno del servidor 500 porque mi secuencia de comandos no estaba formateada correctamente. Analicé el xml devuelto por el servicio web y construí mi mensaje de cadena de soap mirando xml. Finalmente superé el problema con la ayuda de Dan ^ y algo de investigación en Internet. Gracias Dan.

Supere el error de 500 servidores. Ahora puedo obtener una respuesta de falla de inicio de sesión al menos …

 public String MyWebServiceCall() { string strSoapMessage = "" + "" + " " + " " + " [email protected]" + " bar" + " " + " " + ""; 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("[email protected]", "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; } 

Ahora el siguiente problema es pasar las credenciales correctas y procesar la respuesta para hacer otras cosas …

por cierto, aquí estaba la respuesta …

  false 

Editar: El valor falso es correcto, ya que estoy enviando las credenciales incorrectas. Llamo a otras funciones del servicio web de manera similar y pude llamar a todas las funciones del servicio web y recuperar los valores devueltos correspondientes y luego realizar otro procesamiento.

Gracias a todos los que ayudaron a contribuir a resolver el problema.

Saludos