Как получить доступ к веб-сервису PHP от ASP.NET?

Я пробую, используют веб-сервис в веб-приложении ASP.NET C#. Сервис создается в PHP и расположен на некотором удаленном сервере не под моим управлением, таким образом, я не могу изменить его для добавления метаданных или чего-то еще в него.

Когда я использую опцию "Add Web Reference" в Visual Studio 2008, я получаю следующую ошибку:

Документ HTML не содержит информацию для поиска веб-сервиса.

при попытке добавить следующий веб-сервис.

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

Функции веб-сервиса выставлены и отображены в Visual Studio 2008. однако я не мог добавить ссылку на него для использования в Приложении ASP.NET.

t3Service" Описание

Методы __ конструкция ()

create_contact ()

get_contact ()

get_domain_info ()

get_last_error_code ()

get_last_error_msg ()

get_NSSET ()

get_owner_mail ()

вход в систему ()

register_domain ()

register_domain_with_admin_contacts ()

renew_domain ()

request_sendmail ()

send_auth_info ()

transfer_domain ()

  1. Я также попробовал метод wsdl.exe путем получения xml и копирования его в wsdl файл и генерации прокси-класса. Но вывод wsdl содержит предупреждения, и прокси-класс генерировал, пропускает выставленные функции и генерирует что-то вроде этого:

    //CODEGEN: операция, связывающая 'create_contact' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'get_contact' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'get_domain_info' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'get_last_error_code' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'get_last_error_msg' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'get_NSSET' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'get_owner_mail' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'send_auth_info' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'transfer_domain' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'request_sendmail' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операционная привязка 'вход в систему' от пространства имен 'urn:t3' была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'register_domain' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'register_domain_with_admin_contacts' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.//CODEGEN: операция, связывающая 'renew_domain' от пространства имен 'urn:t3', была проигнорирована. Каждая часть сообщения в сообщении use=encoded должна указать тип.

Править:

Я попробовал эту часть кода для кодированного класса моей руки.

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("foo@mydomain.com", "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();
             }  
        }

Но когда я пытаюсь получить ответ затем, он возвращается

Удаленный сервер возвратил ошибку: (500) Внутренняя Ошибка Сервера.

9
задан Benjamin 9 December 2013 в 12:26
поделиться

3 ответа

Как уже упоминалось, вам придется передать код своего «прокси» для этой веб-службы.

Один из примеров выполнения вызова веб-службы вручную - возможно, вам придется немного подправить метод.

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

Я бы порекомендовал создать xsd, который можно использовать для генерации объектов (с помощью xsd.exe), а затем вы можете сериализовать / десериализовать ответы и запросы к реальным объектам.

РЕДАКТИРОВАТЬ: метод GetSoapString ()

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

Для справки Стива

Первый вызов выглядит так:

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

Ответ:

<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>
6
ответ дан 4 December 2019 в 23:05
поделиться

«веб-сервис» - это очень общий термин. Некоторые типы веб-сервисов могут реализовывать WSDL, но это не является обязательным требованием. IIRC требуется интерфейс SOAP для предоставления WSDL, и как nuSOAP, так и расширение PHP SOAP поддерживают WSDL. Таким образом, похоже, что удаленный конец не был реализован должным образом.

1
ответ дан 4 December 2019 в 23:05
поделиться

Редактировать: Раньше я получал внутреннюю ошибку сервера 500, потому что моя строка мыла была неправильно отформатирована. Я проанализировал xml, возвращаемый веб-службой, и построил свое сообщение в виде мыльной строки, просмотрев xml. Наконец, я решил проблему с помощью Дэна ^ и некоторых исследований по Интернет. Спасибо, Дэн.

Я преодолел ошибку сервера 500. Теперь я могу получить ответ об ошибке входа , по крайней мере ...

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

Теперь следующая проблема - передать правильные учетные данные и обработать ответ для других действий ...

кстати, вот ответ ....

<?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>

Изменить: Значение false - ОК, так как я отправляю неправильные учетные данные. Я вызываю другие функции веб-службы аналогичным образом и смог вызвать все функции веб-службы и получить соответствующие возвращаемые значения, а затем выполнить другую обработку.

Спасибо всем, кто помог решить проблему.

С уважением

0
ответ дан 4 December 2019 в 23:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: