C#动态调用带有SoapHeader验证的WebServices

http://blog.csdn.net/u012995964/article/details/54573143

本文记录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();
        }
    }
}

运行后测试结果显示如下:

动态调用运行结果

源码:C#动态调用带有SoapHeader验证的WebServices

posted @ 2017-08-11 17:10  herizai  阅读(...)  评论(... 编辑 收藏