C#動態呼叫帶有SoapHeader驗證的WebServices
阿新 • • 發佈:2019-01-06
本文記錄C#中通過反射動態的呼叫帶有SoapHeader驗證的WebServices服務,基於 Windows8.1、Visual Studio 2013、IIS8 環境實現。
關於WebService建立、部署及靜態呼叫等內容,可以見:C#靜態呼叫帶有SoapHeader驗證的WebServices。
建立動態呼叫類
建立一個客戶端控制檯程式,並新建類DynamicInvokeService.cs
, 檔案內容如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.IO;
using System.Web.Services.Description;
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
namespace DynamicInvoke
{
/// <summary>
/// Web Service服務類
/// </summary>
public class WSHelper
{
/// < summary>
/// 動態呼叫web服務 (不含有SoapHeader)
/// < /summary>
/// < param name="url">WSDL服務地址< /param>
/// < param name="methodname">方法名< /param>
/// < param name="args">引數< /param>
/// < returns>< /returns>
public static object InvokeWebService(string url, string methodname, object[] args)
{
return WSHelper.InvokeWebService(url, null, methodname, null, args);
}
/// <summary>
/// 動態呼叫web服務(含有SoapHeader)
/// </summary>
/// <param name="url"></param>
/// <param name="methodname"></param>
/// <param name="soapHeader"></param>
/// <param name="args"></param>
/// <returns></returns>
public static object InvokeWebService(string url, string methodname, SoapHeader soapHeader, object[] args)
{
return WSHelper.InvokeWebService(url, null, methodname, soapHeader, args);
}
/// < summary>
/// 動態呼叫web服務
/// < /summary>
/// < param name="url">WSDL服務地址< /param>
/// < param name="classname">類名< /param>
/// < param name="methodname">方法名< /param>
/// < param name="args">引數< /param>
/// < returns>< /returns>
public static object InvokeWebService(string url, string classname, string methodname, SoapHeader soapHeader, object[] args)
{
string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";
if ((classname == null) || (classname == ""))
{
classname = WSHelper.GetWsClassName(url);
}
try
{
//獲取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 icc = new CSharpCodeProvider();
//設定編譯引數
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 (cr.Errors.HasErrors)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)
{http://localhost:38076/Properties/
sb.Append(ce.ToString());
sb.Append(System.Environment.NewLine);
}
throw new Exception(sb.ToString());
}
//儲存生產的代理類,預設是儲存在bin目錄下面
TextWriter writer = File.CreateText("MyWebServices.cs");
icc.GenerateCodeFromCompileUnit(ccu, writer, null);
writer.Flush();
writer.Close();
//生成代理例項
System.Reflection.Assembly assembly = cr.CompiledAssembly;
Type t = assembly.GetType(@namespace + "." + classname, true, true);
object obj = Activator.CreateInstance(t);
#region 設定SoapHeader
FieldInfo client = null;
object clientkey = null;
if (soapHeader != null)
{
client = t.GetField(soapHeader.ClassName + "Value");
//獲取客戶端驗證物件 soap類
Type typeClient = assembly.GetType(@namespace + "." + soapHeader.ClassName);
//為驗證物件賦值 soap例項
clientkey = Activator.CreateInstance(typeClient);
//遍歷屬性
foreach (KeyValuePair<string, object> property in soapHeader.Properties)
{
typeClient.GetField(property.Key).SetValue(clientkey, property.Value);
// typeClient.GetProperty(property.Key).SetValue(clientkey, property.Value, null);
}
}
#endregion
if (soapHeader != null)
{
//設定Soap頭
client.SetValue(obj, clientkey);
//pro.SetValue(obj, soapHeader, null);
}
//呼叫指定的方法
System.Reflection.MethodInfo mi = t.GetMethod(methodname);
//方法名錯誤(找不到方法),給出提示
if (null == mi)
{
return "方法名不存在,請檢查方法名是否正確!";
}
return mi.Invoke(obj, args);
// PropertyInfo propertyInfo = type.GetProperty(propertyname);
//return propertyInfo.GetValue(obj, null);
}
catch (Exception ex)
{
throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
}
}
private static string GetWsClassName(string wsUrl)
{
string[] parts = wsUrl.Split('/');
string[] pps = parts[parts.Length - 1].Split('.');
return pps[0];
}
/// <summary>
/// 構建SOAP頭,用於SoapHeader驗證
/// </summary>
public class SoapHeader
{
/// <summary>
/// 構造一個SOAP頭
/// </summary>
public SoapHeader()
{
this.Properties = new Dictionary<string, object>();
}
/// <summary>
/// 構造一個SOAP頭
/// </summary>
/// <param name="className">SOAP頭的類名</param>
public SoapHeader(string className)
{
this.ClassName = className;
this.Properties = new Dictionary<string, object>();
}
/// <summary>
/// 構造一個SOAP頭
/// </summary>
/// <param name="className">SOAP頭的類名</param>
/// <param name="properties">SOAP頭的類屬性名及屬性值</param>
public SoapHeader(string className, Dictionary<string, object> properties)
{
this.ClassName = className;
this.Properties = properties;
}
/// <summary>
/// SOAP頭的類名
/// </summary>
public string ClassName { get; set; }
/// <summary>
/// SOAP頭的類屬性名及屬性值
/// </summary>
public Dictionary<string, object> Properties { get; set; }
/// <summary>
/// 為SOAP頭增加一個屬性及值
/// </summary>
/// <param name="name">SOAP頭的類屬性名</param>
/// <param name="value">SOAP頭的類屬性值</param>
public void AddProperty(string name, object value)
{
if (this.Properties == null)
{
this.Properties = new Dictionary<string, object>();
}
Properties.Add(name, value);
}
}
}
}
注意程式碼中有如下程式碼:
//儲存生產的代理類,預設是儲存在bin目錄下面
TextWriter writer = File.CreateText("MyWebServices.cs");
icc.GenerateCodeFromCompileUnit(ccu, writer, null);
writer.Flush();
writer.Close();
此程式碼可以儲存生成的代理類,可以在工程目錄下的bin目錄下檢視檔案。
測試端程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DynamicInvokeService
{
class Program
{
static void Main(string[] args)
{
string url = "http://192.168.1.109:81/WebService1.asmx";
//string url = "http://192.168.1.109:82/WebService2.asmx";
Dictionary<string, object> properties = new Dictionary<string, object>();
properties.Add("UserName", "admin");
properties.Add("PassWord", "admin123");
DynamicInvoke.WSHelper.SoapHeader soapHeader = new DynamicInvoke.WSHelper.SoapHeader("MySoapHeader", properties);
Object obj1 = DynamicInvoke.WSHelper.InvokeWebService(url, "HelloWorld", null);
Object obj2 = DynamicInvoke.WSHelper.InvokeWebService(url, "HelloWorld", soapHeader, null);
Object obj3 = DynamicInvoke.WSHelper.InvokeWebService(url, "getNum", new Object[] { 1, 2 });
Object obj4 = DynamicInvoke.WSHelper.InvokeWebService(url, "getNum", soapHeader, new Object[] { 1, 2 });
Object obj5 = DynamicInvoke.WSHelper.InvokeWebService(url, "getList", null);
Object obj6 = DynamicInvoke.WSHelper.InvokeWebService(url, "getList", soapHeader, null);
Console.WriteLine("無SoapHeader呼叫HelloWorld:" + obj1);
Console.WriteLine("有SoapHeader呼叫HelloWorld:" + obj2);
Console.WriteLine("無SoapHeader呼叫getNum:" + obj3);
Console.WriteLine("有SoapHeader呼叫getNum:" + obj4);
Console.WriteLine("無SoapHeader呼叫無驗證方法getList:" + obj5.GetType().IsArray);
Console.WriteLine("有SoapHeader呼叫無驗證方法getList:" + obj6);
Console.ReadKey();
}
}
}
執行後測試結果顯示如下: