2010-03-18 141 views
8

我想在C#ASP.Net Web应用程序中使用Web服务。该服务使用PHP构建,位于某些远不在我控制范围内的远程服务器上,因此无法修改它以添加元数据或其他内容。如何从ASP.Net访问PHP Web服务?

当我使用Visual Studio 2008中, “添加Web引用”选项,我收到以下错误:

The HTML document does not contain Web service discovery information.

试图添加下面的Web服务。

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

该网站的服务功能进行曝光,但是我不能引用添加到它在ASP.Net应用程序使用Visual Studio 2008中显示。

t3Service" Description

Methods __construct ()

create_contact ()

get_contact ()

get_domain_info ()

get_last_error_code ()

get_last_error_msg ()

get_NSSET ()

get_owner_mail ()

login ()

register_domain ()

register_domain_with_admin_contacts ( )

renew_domain ()

request_sendmail ()

send_auth_info ()

transfer_domain ()

  • 我还通过检索XML并将其复制到WSDL文件并生成代理类试过Wsdl.exe用方法。但wsdl输出包含警告,并且生成的代理类跳过了公开的函数并生成如下所示的内容:

    // CODEGEN:忽略命名空间'urn:t3'中绑定'create_contact'的操作。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:忽略命名空间'urn:t3'中绑定'get_contact'的操作。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'get_domain_info'的操作被忽略。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'get_last_error_code'的操作被忽略。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:忽略命名空间'urn:t3'中绑定'get_last_error_msg'的操作。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'get_NSSET'的操作被忽略。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:忽略命名空间'urn:t3'中绑定'get_owner_mail'的操作。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'send_auth_info'的操作被忽略。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'transfer_domain'的操作被忽略。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'request_sendmail'的操作被忽略。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:忽略命名空间'urn:t3'的操作绑定'login'。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:忽略命名空间'urn:t3'的操作绑定'register_domain'。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'register_domain_with_admin_contacts'的操作被忽略。 use = encoded消息中的每个消息部分都必须指定一个类型。 // CODEGEN:从命名空间'urn:t3'绑定'renew_domain'的操作被忽略。 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("[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(); 
          } 
         } 
    

    但是,当我试图让响应,那么它将返回

    The remote server returned an error: (500) Internal Server Error.

    回答

    6

    如上所述 - 您必须为此Web服务手动编写您的“代理”。手工制作Web服务调用的

    一个例子 - 你可能需要调整的方法一些。

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

    @Dan非常感谢这段代码。它真的清除了我对这个问题的看法。 你的代码中的每一件事都是可以理解的。但我无法得到/找到名为* GetSoapString *的函数。你可以请告诉它做了什么,这样我可以写我自己的一个,或者如果它已经定义,那么你可以给它的实现或.Net命名空间conatins的定义? – 2010-03-19 03:57:08

    +0

    @丹 我没有尝试你的代码。但试图从服务器获得响应时,我收到以下内容: *远程服务器返回了错误:(500)内部服务器错误。* 这是正常吗?如果是,那么我需要在我的代码中处理这样的响应。 在发布我的问题在stackoverflow之前,我尝试了一些其他的代码,并试图发送一个Web请求,但同样的错误返回。 这是否意味着它需要一些授权或凭证?我清楚地看到一个Login()函数吗?这是造成问题的SSL吗?如果我要将凭据发送到Web服务如何发送它们? – 2010-03-19 04:10:15

    +0

    @Dan * WebResponse webResponse = httpRequest.GetResponse(); * 这是上述错误返回的行。 – 2010-03-19 04:10:57

    1

    “web服务”是一个非常通用的术语。某些类型的Web服务可能实现WSDL - 但它不是必需的。 IIRC需要SOAP接口来提供WSDL,并且nuSOAP和PHP SOAP扩展都支持WSDL。所以看起来远程端没有正确实施。

    0

    编辑: 以前我有500内部服务器错误,因为我的肥皂字符串格式不正确。我分析了从Web服务返回的xml,并通过查看xml构建了我的soap字符串消息。 最后我得到了与帮助的问题从^&在互联网上的研究一些位。谢谢丹。

    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\">[email protected]</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("[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; 
         } 
    

    现在,下一个问题是要通过正确的凭据和处理响应做其他的东西......

    顺便说一句,这里曾是响应....

    <?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好吧,我在错误的凭据要打发。我以类似的方式调用Web服务的其他功能,并能够调用Web服务的所有功能并检索相应的返回值,然后执行其他处理。

    感谢所有谁帮助有助于解决这个问题。

    Regards