C# 为什么在调用web服务时可选xml参数不起作用?
大家好,我是编程新手,正在尝试学习web服务,请帮助我解决这个问题 我正在尝试使用httpWebRequest将soapxml发布到visualstudio中使用以下xmlC# 为什么在调用web服务时可选xml参数不起作用?,c#,asp.net,web-services,soap,wsdl,C#,Asp.net,Web Services,Soap,Wsdl,大家好,我是编程新手,正在尝试学习web服务,请帮助我解决这个问题 我正在尝试使用httpWebRequest将soapxml发布到visualstudio中使用以下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/en
<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留空,它将返回未找到的数据,但是当我使用soapui发送相同的xml时,可以返回正确的天气信息,因为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);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.IO;
使用System.Linq;
Net系统;
使用System.Web;
使用System.Web.UI;
使用System.Web.UI.WebControl;
使用System.Xml;
名称空间分配1.Tests
{
公共部分类task2async:System.Web.UI.Page
{
受保护的无效页面加载(对象发送方、事件参数e)
{
//构建url
UriBuilder_url=新的UriBuilder();
_url.Scheme=“http”;
_url.Host=“www.webservicex.net”;
_url.Path=“globalweather.asmx”;
字符串_action=”http://www.webserviceX.NET/GetWeather";
//创建请求
HttpWebRequest req=(HttpWebRequest)CreateRequest(_url.ToString(),_action);
//正在创建异步请求流
尝试
{
req.BeginGetRequestStream(新的AsyncCallback(GetRequestStreamCallback),req);
}
捕获(例外情况除外)
{
WriteLine(“asyncallback中出现错误”);
}
}
公共静态HttpWebRequestCreateRequest(字符串url,字符串操作)
{
试一试{
//创建httpwebrequest对象
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(url);
添加(“SOAPAction”,action);
request.ContentType=“text/xml;charset=\”UTF-8\”;
request.KeepAlive=true;
request.Method=“POST”;
返回请求;
}
捕获(例外e)
{
返回null;
}
}
公共静态XmlDocument CreateSOApevelop()
{
尝试
{
XmlDocument soapEvelope=新的XmlDocument();
LoadXml(“加拿大”);
返回soapEvelope;
}
捕获(例外e)
{
返回null;
}
}
//使用确保尽快释放未使用的资源
void GetRequestStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest webRequest=(HttpWebRequest)callbackResult.AsyncState;
XmlDocument soapevelop=createSoapEnvelop();
Stream postStream=webRequest.EndGetRequestStream(callbackResult);
soapevelop.Save(postStream);
BeginGetResponse(新的AsyncCallback(GetResponseStreamCallback),webRequest);
}
void GetResponseStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest请求=(HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse=(HttpWebResponse)request.EndGetResponse(callbackResult);
使用(StreamReader httpWebStreamReader=newstreamreader(response.GetResponseStream())
{
字符串结果=httpWebStreamReader.ReadToEnd();
Debug.WriteLine(结果);
}
}
}
}
我可以告诉您哪里出了问题,但我无法确定您需要在哪里调整代码。
请打开您的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>
2.删除代码中的soap信封编码
3.在代码中调用post请求时,通过CityName=string&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";
仅此而已,尽情享受:)我发现这个问题实际上是由请求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;
}
publicstaticxmldocumentcreatesoapenvelope(字符串cityName=“”,字符串countryName=“”)
{
XmlDocument soapEvelope=新的XmlDocument();
soapEvelope.PreserveWhitespace=true;
LoadXml(@“+countryName+”);
返回soapEvelope;
}
谢谢你的回答,也许我没有把我的问题说清楚,我实际上是在尝试使用SOAP方法,而不是http post方法。最后我用SOAP编辑了答案。请检查。为什么不直接使用服务参考?它为你做了所有这些艰苦的工作
string _action = "http://www.webservicex.net/globalweather.asmx";
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;
}