天天看點

C# 動态調用WebService

動态調用webservice,就可以不用添加web引用了,上線的話也隻是需要改一下wsdl位址就可以了 

1.動态調用的方法: 

C# 動态調用WebService

/// <summary>  

        ///  動态webservice調用  

        /// </summary>  

        /// <returns>string</returns>    

        public string wsTest()  

        {  

            string url = "http://localhost:8080/myWebserviceTest/services/myServices?wsdl";//wsdl位址  

            string name = "wsTest";//javaWebService開放的接口  

            WebServiceProxy wsd = new WebServiceProxy(url, name);  

            string[] str = { "測試c#調用java的webService" , "Hello WebService"};  

            string suc = (string)wsd.ExecuteQuery(name, str);  

            return suc;  

        }  

2.動态調用具體類: 

C# 動态調用WebService

using System;  

using System.Collections;  

using System.ComponentModel;  

using System.Data;  

using System.Linq;  

using System.Web;  

using System.Web.Services;  

using System.Web.Services.Protocols;  

using System.Xml.Linq;  

using System.IO;  

using System.Net;  

using System.CodeDom;  

using System.CodeDom.Compiler;  

using System.Web.Services.Description;  

using System.Xml.Serialization;  

using System.Web.Services.Discovery;  

using System.Xml.Schema;  

using System.Text;  

using System.Security.Cryptography;  

using System.Reflection;  

using System.Collections.Generic;  

using System.Xml;  

namespace TPSVService  

{  

    /// <summary>  

    /// WebServiceProxy 的摘要說明  

    /// </summary>  

    [WebService(Namespace = "http://tempuri.org/")]  

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  

    [ToolboxItem(false)]  

    // 若要允許使用 ASP.NET AJAX 從腳本中調用此 Web 服務,請取消對下行的注釋。  

    // [System.Web.Script.Services.ScriptService]  

    public class WebServiceProxy : System.Web.Services.WebService  

    {  

        #region 私有變量和屬性定義  

        /// <summary>                   

        /// web服務位址                           

        /// </summary>                              

        private string _wsdlUrl = string.Empty;  

        /// web服務名稱                           

        private string _wsdlName = string.Empty;  

        /// 代理類命名空間                           

        private string _wsdlNamespace = "FrameWork.WebService.DynamicWebServiceCalling.{0}";  

        /// 代理類類型名稱                           

        private Type _typeName = null;  

        /// 程式集名稱                             

        private string _assName = string.Empty;  

        /// 代理類所在程式集路徑                            

        private string _assPath = string.Empty;  

        /// 代理類的執行個體                            

        private object _instance = null;  

        private object Instance  

            get  

            {  

                if (_instance == null)  

                {  

                    _instance = Activator.CreateInstance(_typeName);  

                    return _instance;  

                }  

                else  

            }  

        #endregion  

        #region 構造函數  

        public WebServiceProxy(string wsdlUrl)  

            this._wsdlUrl = wsdlUrl;  

            string wsdlName = WebServiceProxy.getWsclassName(wsdlUrl);  

            this._wsdlName = wsdlName;  

            this._assName = string.Format(_wsdlNamespace, wsdlName);  

            this._assPath = Path.GetTempPath() + this._assName + getMd5Sum(this._wsdlUrl) + ".dll";  

            this.CreateServiceAssembly();  

        public WebServiceProxy(string wsdlUrl, string wsdlName)  

        #region 得到WSDL資訊,生成本地代理類并編譯為DLL,構造函數調用,類生成時加載  

        /// <summary>                           

        /// 得到WSDL資訊,生成本地代理類并編譯為DLL                           

        private void CreateServiceAssembly()  

            if (this.checkCache())  

                this.initTypeName();  

                return;  

            if (string.IsNullOrEmpty(this._wsdlUrl))  

            try  

                //使用WebClient下載下傳WSDL資訊                         

                WebClient web = new WebClient();  

                Stream stream = web.OpenRead(this._wsdlUrl);  

                ServiceDescription description = ServiceDescription.Read(stream);//建立和格式化WSDL文檔  

                ServiceDescriptionImporter importer = new ServiceDescriptionImporter();//建立用戶端代理代理類  

                importer.ProtocolName = "Soap";  

                importer.Style = ServiceDescriptionImportStyle.Client;  //生成用戶端代理                         

                importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;  

                importer.AddServiceDescription(description, null, null);//添加WSDL文檔  

                //使用CodeDom編譯用戶端代理類                   

                CodeNamespace nmspace = new CodeNamespace(_assName);    //為代理類添加命名空間                  

                CodeCompileUnit unit = new CodeCompileUnit();  

                unit.Namespaces.Add(nmspace);  

                this.checkForImports(this._wsdlUrl, importer);  

                ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);  

                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");  

                CompilerParameters parameter = new CompilerParameters();  

                parameter.ReferencedAssemblies.Add("System.dll");  

                parameter.ReferencedAssemblies.Add("System.XML.dll");  

                parameter.ReferencedAssemblies.Add("System.Web.Services.dll");  

                parameter.ReferencedAssemblies.Add("System.Data.dll");  

                parameter.GenerateExecutable = false;  

                parameter.GenerateInMemory = false;  

                parameter.IncludeDebugInformation = false;  

                CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);  

                provider.Dispose();  

                if (result.Errors.HasErrors)  

                    string errors = string.Format(@"編譯錯誤:{0}錯誤!", result.Errors.Count);  

                    foreach (CompilerError error in result.Errors)  

                    {  

                        errors += error.ErrorText;  

                    }  

                    throw new Exception(errors);  

                this.copyTempAssembly(result.PathToAssembly);  

            catch (Exception e)  

                throw new Exception(e.Message);  

        #region 執行Web服務方法  

        /// 執行代理類指定方法,有傳回值                                

        /// </summary>                                  

        /// <param   name="methodName">方法名稱</param>                           

        /// <param   name="param">參數</param>                              

        /// <returns>object</returns>                                 

        public object ExecuteQuery(string methodName, object[] param)  

            object rtnObj = null;   

            string[] args = new string[2];  

            List<string> list = new List<string>();  

            List<string> list1 = new List<string>();  

            List<string> list2 = new List<string>();  

            object[] obj = new object[3];  

                if (this._typeName == null)  

                    //記錄Web服務通路類名錯誤日志代碼位置  

                    throw new TypeLoadException("Web服務通路類名【" + this._wsdlName + "】不正确,請檢查!");  

                //調用方法  

                MethodInfo mi = this._typeName.GetMethod(methodName);  

                if (mi == null)  

                    //記錄Web服務方法名錯誤日志代碼位置  

                    throw new TypeLoadException("Web服務通路方法名【" + methodName + "】不正确,請檢查!");  

                try  

                    if (param == null)  

                        rtnObj = mi.Invoke(Instance, null);  

                    else {  

                        list.Add("Hello ");  

                        list.Add("WebService ");  

                        list.Add(" ! ");  

                        list1.Add("I ");  

                        list1.Add("am ");  

                        list1.Add("test ");  

                        list2.Add("do ");  

                        list2.Add("it ");  

                        list2.Add("now ");  

                        obj[0] = list;  

                        obj[1] = list1;  

                        obj[2] = list2;  

                        rtnObj = mi.Invoke(Instance, new object[] { obj });  

                        //rtnObj = mi.Invoke(Instance, new object[] { param });  

                catch (TypeLoadException tle)  

                    //記錄Web服務方法參數個數錯誤日志代碼位置  

                    throw new TypeLoadException("Web服務通路方法【" + methodName + "】參數個數不正确,請檢查!", new TypeLoadException(tle.StackTrace));  

            catch (Exception ex)  

                throw new Exception(ex.Message, new Exception(ex.StackTrace));  

            return rtnObj;  

        /// 執行代理類指定方法,無傳回值                                

        public void ExecuteNoQuery(string methodName, object[] param)  

                        mi.Invoke(Instance, null);  

                    else  

                        mi.Invoke(Instance, param);  

        #region 私有方法  

        /// <summary>                               

        /// 得到代理類類型名稱                                 

        private void initTypeName()  

            Assembly serviceAsm = Assembly.LoadFrom(this._assPath);  

            Type[] types = serviceAsm.GetTypes();  

            string objTypeName = "";  

            foreach (Type t in types)  

                if (t.BaseType == typeof(SoapHttpClientProtocol))  

                    objTypeName = t.Name;  

                    break;  

            _typeName = serviceAsm.GetType(this._assName + "." + objTypeName);  

        /// <summary>                       

        /// 根據web   service文檔架構向代理類添加ServiceDescription和XmlSchema                             

        /// <param   name="baseWSDLUrl">web服務位址</param>                           

        /// <param   name="importer">代理類</param>                              

        private void checkForImports(string baseWsdlUrl, ServiceDescriptionImporter importer)  

            DiscoveryClientProtocol dcp = new DiscoveryClientProtocol();  

            dcp.DiscoverAny(baseWsdlUrl);  

            dcp.ResolveAll();  

            foreach (object osd in dcp.Documents.Values)  

                if (osd is ServiceDescription) importer.AddServiceDescription((ServiceDescription)osd, null, null); ;  

                if (osd is XmlSchema) importer.Schemas.Add((XmlSchema)osd);  

        /// 複制程式集到指定路徑                                

        /// <param   name="pathToAssembly">程式集路徑</param>                              

        private void copyTempAssembly(string pathToAssembly)  

            File.Copy(pathToAssembly, this._assPath);  

        private string getMd5Sum(string str)  

            Encoder enc = System.Text.Encoding.Unicode.GetEncoder();  

            byte[] unicodeText = new byte[str.Length * 2];  

            enc.GetBytes(str.ToCharArray(), 0, str.Length, unicodeText, 0, true);  

            MD5 md5 = new MD5CryptoServiceProvider();  

            byte[] result = md5.ComputeHash(unicodeText);  

            StringBuilder sb = new StringBuilder();  

            for (int i = 0; i < result.Length; i++)  

                sb.Append(result[i].ToString("X2"));  

            return sb.ToString();  

        /// 是否已經存在該程式集                                

        /// <returns>false:不存在該程式集,true:已經存在該程式集</returns>                                

        private bool checkCache()  

            if (File.Exists(this._assPath))  

                return true;  

            return false;  

        //私有方法,預設取url入口的檔案名為類名  

        private static string getWsclassName(string wsdlUrl)  

            string[] parts = wsdlUrl.Split('/');  

            string[] pps = parts[parts.Length - 1].Split('.');  

            return pps[0];  

    }  

}  

java接口可以用Object[]類型接收參數 

建立個c#的webservice應用,可以運作本示例