大家好我是编程和尝试学习网络服务的新手,请帮我解决这个问题!
我正在尝试使用httpWebRequest将soap xml发布到http://www.webservicex.net/globalweather.asmx,使用以下xml和visual studio。
<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留空,则返回Data Not Found,但是当我使用soap 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 :(得分: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>
您正在尝试按照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>
请相应地修改您的代码。请在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.删除代码中的soap包围创作。
3.在代码中调用post请求时,传递CityName = string&amp; CountryName = string 而不是肥皂信封。
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";
多数民众赞成,享受:)
答案 1 :(得分: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;
}