C#调⽤Java的WebService的3种⽅式关于soapheader调⽤,可以参考
1.问题描述
调⽤的Java的webservice
string Invoke(string func, string reqXml)
 使⽤C#直接调⽤⼀直报错。
webservice提供⽅有说明如下:
1 2 3 4 5 6 7 8 9 10 11 12 13⾝份验证采⽤对SOAP⾝份认证(⽤户名/密码验证/序列号)的⽅式部署,设定⽤户名和密码由系统配置,所有⽂本内容编码选择UTF-8编码规范<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="/soap/envelope/">
<soapenv:Header>
<vc:Authentication xmlns: vc ="ant">
<vc:Username>[系统配置] </vc:Username>
<vc:Password>[系统配置]</vc:Password>
<vc:SerialNo>[系统配置]</vc:SerialNo>
</vc:Authentication>
</soapenv:Header>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>
相信就是soapenv:Header这⾥的问题了,C# 没soapenv:Header这些东西的
⽹上查了好多类似下⾯的
都没有⽤
后来尝试sopui及xmlspy创建soap,直接发送xml,终于试出来了,然后C#使⽤http post调⽤webservice,成功了。
2.问题解决1
C#拼接的需要http post的soap字符串如下
</SOAP-ENV:Header> 照搬给的⽂档⾥的字符串
<SOAP-ENV:Body> 为调⽤函数,string Invoke(string func, string reqXml) 函数名Invoke,两个参数,⾃⾏理解吧
注意:⾥⾯的\r\n换⾏标志都要保留,不然都是报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22string soap = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"+
"<SOAP-ENV:Envelope\r\n"+
"xmlns:SOAP-ENV=\"/soap/envelope/\"\r\n"+              "xmlns:SOAP-ENC
=\"/soap/encoding/\"\r\n"+              "xmlns:xsi=\"/2001/XMLSchema-instance\"\r\n"+
"xmlns:xsd=\"/2001/XMLSchema\">\r\n"+
"<SOAP-ENV:Header>\r\n"+
"<vc:Authentication\r\n"+
"xmlns:vc=\"ant\">\r\n"+
"<vc:Username>xx</vc:Username>\r\n"+
"<vc:Password>xxx</vc:Password>\r\n"+
"<vc:SerialNo>xxxx</vc:SerialNo>\r\n"+
"</vc:Authentication>\r\n"+
"</SOAP-ENV:Header>\r\n"+
"<SOAP-ENV:Body>\r\n"+
"<m:Invoke\r\n"+
"xmlns:m=\"/\">\r\n"+
"<m:func>"+ jkid + "</m:func>\r\n"+
"<m:reqXml>"+ HttpUtility.HtmlEncode(xml) + "</m:reqXml>\r\n"+                  "</m:Invoke>\r\n"+
调用webservice服务"</SOAP-ENV:Body>\r\n"+
"</SOAP-ENV:Envelope>";
  然后发送,随便个http post的代码就⾏了1
2
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20public static string GetSOAPReSource(string url, string datastr)
{
try
{
//request
Uri uri = new Uri(url);
WebRequest webRequest = WebRequest.Create(uri);
webRequest.ContentType = "text/xml; charset=utf-8";
webRequest.Method = "POST";
using(Stream requestStream = webRequest.GetRequestStream())
{
byte[] paramBytes = Encoding.UTF8.GetBytes(datastr.ToString());
requestStream.Write(paramBytes, 0, paramBytes.Length);
}
/
/response
WebResponse webResponse = webRequest.GetResponse();
using(StreamReader myStreamReader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))              {
string result = "";
2021222324252627
28
return  result = myStreamReader.ReadToEnd();              }
}
catch  (Exception ex)
{
throw  ex;          }      } 
3.问题解决2
发现还是报错,http 500错误,和之前不⼀样,但依然不对
研究webservice 的wsdl
发现了问题
调⽤时加上
1<strong>webRequest.Headers.Add("SOAPAction", "/IAjsjService/Invoke");<br><br></strong>终于成功了
1
2
345678910111213141516171819202122232425262728
29
public  static  string  GetSOAPReSource(string  url, string  datastr)
{
try            {              //request                Uri uri = new  Uri(url);              WebRequest webRequest = WebRequest.Create(uri);
webRequest.ContentType = "text/xml; charset=utf-8";
webRequest.Headers.Add("SOAPAction", "/IAjsjService/Invoke");
webRequest.Method = "POST";              using  (Stream requestStream = webRequest.GetRequestStream())              {                  byte[] paramBytes = Encoding.UTF8.GetBytes(datastr.ToString());
requestStream.Write(paramBytes, 0, paramBytes.Length);
}
//response                WebResponse webResponse = webRequest.GetResponse();              using  (StreamReader myStreamReader = new  StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))              {
string  result = "";
return  result = myStreamReader.ReadToEnd();
}
}
catch  (Exception ex)
{              throw  ex;          }      } 
其他调⽤webservice 的⽅式:
上⼀篇链接如上,更像是  来处理xml ,解决复杂的认证
⼜遇到⼀家
⾝份验证采⽤对SOAP ⾝份认证(⽤户名/密码验证/序列号)的⽅式部署,设定⽤户名和密码由系统配置,所有⽂本内容编码选择UTF-8编码规范
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="/soap/envelope/">
<soapenv:Header>
<vc:Authentication xmlns: vc ="ant">
<vc:Username>[系统配置] </vc:Username>
<vc:Password>[系统配置]</vc:Password>
<vc:SerialNo>[系统配置]</vc:SerialNo >
</vc:Authentication>
</soapenv:Header>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>
wsdl 的xml 如下
<?xml version="1.0" encoding="utf-8"?><wsdl:definitions name="AjsjService" targetNamespace="/" xmlns:wsdl="/wsdl/" xmlns:xsd="/2001/XMLSchema" xmlns:soapenc="sch 使⽤添加服务引⽤加到项⽬⾥
不要⽤⾼级那⾥的添加web引⽤添加,不然后⾯没法做
⽣成的Reference.cs如下
//------------------------------------------------------------------------------
// <auto-generated>
//    此代码由⼯具⽣成。
//    运⾏时版本:4.0.30319.1026
//
//    对此⽂件的更改可能会导致不正确的⾏为,并且如果
//    重新⽣成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace v {
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="V.IAjsjService")]
public interface IAjsjService {
[System.ServiceModel.OperationContractAttribute(Action="/IAjsjService/Invoke", ReplyAction="/IAjsjService/InvokeResponse")]
string Invoke(string func, string reqXml);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IAjsjServiceChannel : v.IAjsjService, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class AjsjServiceClient : System.ServiceModel.ClientBase<v.IAjsjService>, v.IAjsjService {
public AjsjServiceClient() {
}
public AjsjServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public AjsjServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public AjsjServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public AjsjServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public string Invoke(string func, string reqXml) {
return base.Channel.Invoke(func, reqXml);
}
}
}
调⽤⽅法:
定义soapheader
public class MySoapHeader
{
string username;//⽤户名
string password;//密码
string serialNo;//序列号
public MySoapHeader()
{ }
public MySoapHeader(string u, string p, string s)
{
Username = u;
Password = p;
SerialNo = s;
}
public string Username
{
get { return username; }
set { username = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
public string SerialNo
{
get { return serialNo; }
set { serialNo = value; }
}
}
调⽤
MySoapHeader myHeader = new MySoapHeader(m_user, m_pw, m_serial);
ServiceReference.AjsjServiceClient client = new ServiceReference.AjsjServiceClient("BasicHttpBinding_IAjsjService", m_serverUrl);
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
MessageHeader header = MessageHeader.CreateHeader("Authentication", "ant", myHeader);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
client.Invoke(func, strXml);
1.直接调⽤
已知webservice路径,则可以直接添加服务引⽤--⾼级--添加web引⽤直接输⼊webservice URL。这个⽐较常见也很简单即有完整的webservice⽂件⽬录如下图所⽰,
也可以在本地IIS根据webservice⽂件⽬录新发布⼀个webservice,然后程序动态调⽤,修改Url
1public new string Url { set; get; }
2.根据wsdl⽂件⽣成webservice 的.cs⽂件及⽣成dll C#调⽤
有时没有这么多⽂件,只有wsdl⽂件
wsdl⽂件可以有别⼈提供或者根据webservice地址获取:
Visual Studio 2013->Visual Studio Tools->VS2013 开发⼈员命令提⽰
命令⾏输⼊
wsdl E:\WS.wsdl /out:WS.cs
E:\WS.wsdl  是wsdl⽂件存储路径,也可以是localhost:8888/WS.asmx?wsdl
不报错的话,看路径下 Program Files\Microsoft Visual Studio 12.0\WS.cs已经⾃动⽣成
.cs⽂件看函数声明,结构体等都⾮常⽅便
然后命令⾏执⾏
csc /t:library WS.cs
同样的路径下,⽣成了WS.dll,拷贝出去放到项⽬⽂件夹下,C# winform程序也可以添加引⽤了。
⽣成的⽂件默认在这⾥:
默认⽣成的SOAP版本为1.1,可以
G:\Program Files\Microsoft Visual Studio 12.0>wsdl E:\e.wsdl /protocol:SOAP12 /out:e.cs
来指定1.2
3.C# 动态调⽤WebService
在C#程序中,若要调⽤WebService,⼀般是采⽤"添加Web引⽤"的⽅式来实现的。但如果此WebService的URL是在程序运⾏过程中才能获得的,那怎么办呢?那就必须是"动态"调⽤这个WebService了。
举个使⽤它的例⼦:
object[] args = new object[1];
args.SetValue("cyy_JS", 0);
DataTable dt = WebServiceHelper.InvokeWebService("192.168.0.10/DBMS_CYY/DBMS_Service.asmx", "GetUserTreeListData", args) as DataTable;
恩~有点⿇烦,这意味着每次我都要把想调⽤的函数的参数组织成⼀个object[]才⾏,且每次调⽤InvokeWebService都是在内存中创建动态程序集,效率极低。则次种⽅法绝对没有直接⽤“实例名.⽅法名(参数列表)”来的舒服。
我把它放到⼀个叫WebServiceHelper.cs的类⾥⾯了。
1
2
3
4
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52using System.IO;
using System.Web.Services.Description;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.CodeDom;
/// <summary>
/// 动态调⽤WebService
/// </summary>
/// <param name="url">WebService地址</param>
/// <param name="classname">类名</param>
/// <param name="methodname">⽅法名(模块名)</param>
/// <param name="args">参数列表</param>
/// <returns>object</returns>
public static object InvokeWebService(string url, string classname, string methodname, object[] args)        {
string@namespace= "ServiceBase.WebService.DynamicWebLoad";
if(classname == null|| classname == "")
{
classname = WebServiceHelper.GetClassName(url);
}
//获取服务描述语⾔(WSDL)
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(url + "?WSDL");
ServiceDescription sd = ServiceDescription.Read(stream);
ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
sdi.AddServiceDescription(sd, "", "");
CodeNamespace cn = new CodeNamespace(@namespace);
//⽣成客户端代理类代码
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(cn);
sdi.Import(cn, ccu);
CSharpCodeProvider csc = new CSharpCodeProvider();
ICodeCompiler icc = csc.CreateCompiler();
//设定编译器的参数
CompilerParameters cplist = new CompilerParameters();
cplist.GenerateExecutable = false;
cplist.GenerateInMemory = true;
cplist.ReferencedAssemblies.Add("System.dll");
cplist.ReferencedAssemblies.Add("System.XML.dll");
cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
cplist.ReferencedAssemblies.Add("System.Data.dll");
//编译代理类
CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
if(true== cr.Errors.HasErrors)
{
System.Text.StringBuilder sb = new StringBuilder();
foreach(CompilerError ce in cr.Errors)
{
sb.Append(ce.ToString());
sb.Append(System.Environment.NewLine);
}
throw new Exception(sb.ToString());
}
//⽣成代理实例,并调⽤⽅法

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。