2013-12-22 52 views
0

嗨,大家好我是新手編程和嘗試學習Web服務,請幫助我解決這個問題!爲什麼可選的xml參數在調用Web服務時不起作用?

我試圖使用httpWebRequest發佈肥皂xml到http://www.webservicex.net/globalweather.asmx使用以下與Visual Studio的XML。

<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> 
<GetWeather xmlns='http://www.webserviceX.NET'> 
<CountryName>Canada</CountryName> 
<CityName></CityName> 
</GetWeather> 
</soap:Body> 
</soap:Envelope> 

這裏的問題是,如果我離開CITYNAME空白,它返回的數據沒有發現,但是當我用肥皂UI發送相同的XML,可以返回正確的氣象信息,因爲WSDL http://www.webservicex.net/globalweather.asmx?WSDL指出CITYNAME是可選。

希望如果有人能告訴我,我怎麼能得到這個工作。

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Xml; 

namespace Assignment1.Tests 
{ 
    public partial class task2async : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
      //build url 
      UriBuilder _url = new UriBuilder(); 

      _url.Scheme = "http"; 
      _url.Host = "www.webservicex.net"; 
      _url.Path = "globalweather.asmx"; 
      string _action = "http://www.webserviceX.NET/GetWeather"; 
      //creating a request 
      HttpWebRequest req=(HttpWebRequest)CreateRequest(_url.ToString(), _action); 
      //being async request stream 
      try 
      { 
       req.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), req); 
      } 
      catch (Exception ex) 
      { 

       Debug.WriteLine("Something wrong at asyncallback"); 
      } 
     } 
     public static HttpWebRequest CreateRequest (string url, string action) 
     { 
      try { 
       //creating httpwebrequest object 
       HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
       request.Headers.Add("SOAPAction", action); 
       request.ContentType = "text/xml;charset=\"UTF-8\""; 
       request.KeepAlive = true; 
       request.Method = "POST"; 
       return request; 
      } 
      catch(Exception e) 
      { 
       return null; 
      } 
     } 

     public static XmlDocument createSoapEnvelop() 
     { 
      try 
      { 
       XmlDocument soapEvelope = new XmlDocument(); 
       soapEvelope.LoadXml("<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><GetWeather xmlns='http://www.webserviceX.NET'><CountryName>Canada</CountryName><CityName></CityName></GetWeather></soap:Body></soap:Envelope>"); 
       return soapEvelope; 

      } 
      catch (Exception e) 
      { 
       return null; 
      } 

     } 
     // using makes sure unused resources are released as soon 


     void GetRequestStreamCallback(IAsyncResult callbackResult) 
     { 
      HttpWebRequest webRequest = (HttpWebRequest)callbackResult.AsyncState; 
      XmlDocument soapevelop = createSoapEnvelop(); 
      Stream postStream = webRequest.EndGetRequestStream(callbackResult); 
      soapevelop.Save(postStream); 
      webRequest.BeginGetResponse(new AsyncCallback(GetResponseStreamCallback), webRequest); 

     } 

     void GetResponseStreamCallback(IAsyncResult callbackResult) 
     { 
      HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState; 
      HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult); 
      using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream())) 
      { 
       string result = httpWebStreamReader.ReadToEnd(); 
       Debug.WriteLine(result); 
      } 
     }  
    } 
} 
+0

爲什麼不只是使用服務引用?它爲你做了所有這些努力 –

回答

0

我發現,這個問題實際上是由引起請求xml中包含的空白,我通過添加soapEvelop.PreserveWhitespace = true來解決此問題;

public static XmlDocument createSoapEnvelop(string cityName="", string countryName="") 
    { 
     XmlDocument soapEvelope = new XmlDocument(); 
     soapEvelope.PreserveWhitespace = true; 
     soapEvelope.LoadXml(@"<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><GetWeather xmlns=""http://www.webserviceX.NET""><CityName></CityName><CountryName>"+countryName+"</CountryName></GetWeather></soap:Body></soap:Envelope>"); 
     return soapEvelope; 
    } 
1

我可以告訴你,你去哪兒錯了,雖然我不能夠找出你在哪裏需要調整你的代碼。 請打開您的wsdl並在wsdl結尾查看服務標籤。你會發現4個端口。

<wsdl:service name="GlobalWeather"> 
<wsdl:port name="GlobalWeatherSoap" binding="tns:GlobalWeatherSoap"> 
    <soap:address location="http://www.webservicex.net/globalweather.asmx" /> 
</wsdl:port> 
<wsdl:port name="GlobalWeatherSoap12" binding="tns:GlobalWeatherSoap12"> 
    <soap12:address location="http://www.webservicex.net/globalweather.asmx" /> 
</wsdl:port> 
<wsdl:port name="GlobalWeatherHttpGet" binding="tns:GlobalWeatherHttpGet"> 
    <http:address location="http://www.webservicex.net/globalweather.asmx" /> 
</wsdl:port> 
<wsdl:port name="GlobalWeatherHttpPost" binding="tns:GlobalWeatherHttpPost"> 
    <http:address location="http://www.webservicex.net/globalweather.asmx" /> 
</wsdl:port> 

您嘗試,而你是你的providng輸入作爲每GlobalWeatherSoap執行GlobalWeatherHttpPost。 這就是問題所在。 如果你想使用httppost方法,那麼這將是你的操作。

<wsdl:operation name="GetWeather"> <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</wsdl:documentation> <wsdl:input message="tns:GetWeatherHttpPostIn" /> <wsdl:output message="tns:GetWeatherHttpPostOut" /> </wsdl:operation>

而且你需要實現按以下綁定,

<wsdl:binding name="GlobalWeatherHttpPost" type="tns:GlobalWeatherHttpPost"> 
<http:binding verb="POST" /> 
<wsdl:operation name="GetWeather"> 
    <http:operation location="/GetWeather" /> 
    <wsdl:input> 
    <mime:content type="application/x-www-form-urlencoded" /> 
    </wsdl:input> 
    <wsdl:output> 
    <mime:mimeXml part="Body" /> 
    </wsdl:output> 
</wsdl:operation> 
<wsdl:operation name="GetCitiesByCountry"> 
    <http:operation location="/GetCitiesByCountry" /> 
    <wsdl:input> 
    <mime:content type="application/x-www-form-urlencoded" /> 
    </wsdl:input> 
    <wsdl:output> 
    <mime:mimeXml part="Body" /> 
    </wsdl:output> 
</wsdl:operation> 

請修改代碼accordingly.Refer輸入和輸出消息格式的WSDL進行此項操作。

編輯您的代碼更正: 「但是,當我使用soap ui發送相同的xml時,可以返回正確的天氣信息,因爲WSDL http://www.webservicex.net/globalweather.asmx?WSDL指出CityName是可選的。

在soapui中,它將爲soap操作創建rquest,而不是httpget和httppost。

要實現httppost: 1.去除代碼中的這個

request.Headers.Add("SOAPAction", action); 

2.取出肥皂信封creaation。

3.while在您的代碼中調用發佈請求傳遞CityName = string & CountryName = string 而不是soap信封。

string str = "CountryName=Canada"; 
byte[] postBytes = Encoding.ASCII.GetBytes(str); 
request.ContentType = "text"; 
request.ContentLength = postBytes.Length; 
Stream postStream = request.GetRequestStream(); 
postStream.Write(postBytes, 0, postBytes.Length); 

使用SOAP 1。1:

編輯這行代碼的,

string _action = "http://www.webserviceX.NET/GetWeather"; 

string _action = "http://www.webservicex.net/globalweather.asmx"; 

那是全部替換,享受:)

+0

感謝您的回答,也許我沒有讓我的問題清楚,我實際上正在嘗試使用SOAP方法,而不是http post方法。 –

+0

好的,虐待根據需要編輯答案。 – kingAm

+0

我在最後使用SOAP編輯了答案。請檢查。 – kingAm

相關問題