下图为我利用SOAPUI进行测试,发送请求内容如左所示,右边是返回的response.
下图为我基于C#发送soap请求的程序
下图是返回的结果,返回内容为我要调用的webservice服务内容
请问,错误出在哪里呢?跪谢
太长..只是说下别的.
为什么不直接用生成的代理类?
生成代理类的处理方法,验证失败。
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Text;
using System.Windows.Controls;
using System.Xml.Linq;
using VMS.Controls;
using VMS.Utils;
using VMS.Views.MainPageItems.QueryItems.ParamQueryControlItems;
namespace VMS.Views.MainPageItems.QueryItems
{
public abstract class QueryBase : UserControl, IReflactor
{
public const string SpaceName = "VMS.Views.MainPageItems.QueryItems.BussinessQuerys.";
public static readonly Assembly CurrentAssembly = Assembly.GetExecutingAssembly();
public static readonly string CurrentAssemblyName = CurrentAssembly.FullName;
protected QueryBase()
{
ParamsQuery = new List<IParamQuery>();
LoadingForm = new LoadingWindow();
SetFunParamValues(CreateQueryParams());
DownloadSucesss += OnDownloadData;
}
public string Data { get; private set; }
/// <summary>
/// 除去Host的相对Uri
/// </summary>
public abstract string Uri { get; }
public abstract string Fun { get; }
public List<IParamQuery> ParamsQuery { get; private set; }
public LoadingWindow LoadingForm { get; private set; }
public virtual string Caption
{
get { return GetType().Name; }
}
public virtual string FullName
{
get { return GetType().FullName; }
}
public event Action<string> DownloadSucesss;
public virtual event Action<Exception> OnError;
private void SetFunParamValues(IList<IParamQuery> paramsControls)
{
if (paramsControls == null) return; //throw new FormatException("查询参数不能为NULL");
ParamsQuery.AddRange(paramsControls);
}
protected abstract IList<IParamQuery> CreateQueryParams();
private string CreateBody()
{
var contentBody = new StringBuilder();
contentBody.Append("<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">");
contentBody.Append(
"<s:Body xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
contentBody.AppendFormat("<{0} xmlns=\"http://tempuri.org/\">", Fun);
foreach (IParamQuery funParam in ParamsQuery)
contentBody.AppendFormat("<{0}>{1}</{0}>", funParam.PName, funParam.PValue);
contentBody.AppendFormat("</{0}>", Fun);
contentBody.Append("</s:Body>");
contentBody.Append("</s:Envelope>");
return contentBody.ToString();
}
protected abstract Exception Validate();
protected virtual bool ValidateDealling(Exception ex)
{
if (ex == null)
{
return true;
}
if (OnError != null) OnError.Invoke(ex);
return false;
}
public virtual void LoadData()
{
if (LoadingForm.IsDownloading) return;
if (!ValidateDealling(Validate())) return;
LoadingForm.Show();
var webClient = new WebClient();
webClient.UploadStringCompleted += (sender, args) =>
{
if (!LoadingForm.IsDownloading) return;
if (args.Error != null)
{
if (OnError != null) OnError.Invoke(new NetWorkException("网络错误", args.Error));
}
else if (args.Result == null)
{
if (OnError != null) OnError.Invoke(new NetWorkException("数据错误", args.Error));
}
else
{
try
{
XDocument doc = XDocument.Parse(args.Result);
Data = doc.Root.Value;
if (DownloadSucesss != null) DownloadSucesss.Invoke(Data);
}
catch (Exception ex)
{
OnError.Invoke(new NetWorkException("数据读取错误", ex));
}
}
LoadingForm.Close();
};
webClient.Headers["SOAPAction"] = string.Format("http://tempuri.org/{0}", Fun);
webClient.Headers["Content-Type"] = "text/xml; charset=utf-8";
string soapBody = CreateBody();
webClient.UploadStringAsync(
new Uri(string.Format("http://{0}:8001/{1}", WebServiceHelper.Host, Uri), UriKind.Absolute), soapBody);
}
protected abstract void OnDownloadData(string content);
}
}
参见以上silverlight code;
看了一下你的代码,两个地方:
1、你GetEncodeString()是用来干吗的?
我觉得你应该直接将你的soap类型的xml字符串,直接转成bytes,然后写到stream里面就可以了,调用GetEncodeString没必要。
2、ContentType你确定你用soap的时候不应该写application/soap+xml?
当然,有些服务器经过配置或者一些人手写的不严谨的服务器会无视ContentType的错误或者不符合规范,但是,按照SOAP的规范,请求类型应该是POST(这点你对了),请求的ContentType类型应该是application/soap+xml,具体数据内容放在Stream中。就这三点。
好了,总结以上两点,希望对你有帮助。
GetEncodeString()是服务提供方说需要进行Base64转换。另外,我试了一下,如果我把soap的body全部给注释掉,返回的也是服务wsdl的全部内容
楼主解决了吗
楼主解决了吗