C# 为什么在调用web服务时可选xml参数不起作用?

C# 为什么在调用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

大家好,我是编程新手,正在尝试学习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/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;
    }