1. 程式人生 > >C# 呼叫WebService的3種方式 :直接呼叫、根據wsdl生成webservice的.cs檔案及生成dll呼叫、動態呼叫

C# 呼叫WebService的3種方式 :直接呼叫、根據wsdl生成webservice的.cs檔案及生成dll呼叫、動態呼叫

1.直接呼叫

已知webservice路徑,則可以直接 新增服務引用--高階--新增web引用 直接輸入webservice URL。這個比較常見也很簡單

即有完整的webservice檔案目錄如下圖所示,

也可以在本地IIS根據webservice檔案目錄新發佈一個webservice,然後程式動態呼叫,修改Url

1

public new string Url { set; get; }

 

 

2.根據wsdl檔案生成webservice 的.cs檔案 及 生成dll C#呼叫  

有時沒有這麼多檔案,只有wsdl檔案

wsdl檔案可以有別人提供或者根據webservice地址獲取:

http://localhost:8888/WS.asmx?wsdl

 

 

 

Visual Studio 2013->Visual Studio Tools->VS2013 開發人員命令提示

 

 

命令列輸入

wsdl E:\WS.wsdl /out:WS.cs

 

E:\WS.wsdl  是wsdl檔案儲存路徑,也可以是http://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("http://192.168.0.10/DBMS_CYY/DBMS_Service.asmx", "GetUserTreeListData", args) as DataTable;  

 

 

恩~有點麻煩,這意味著每次我都要把想呼叫的函式的引數組織成一個object[]才行,且每次呼叫InvokeWebService都是在記憶體中建立動態程式集,效率極低。則次種方法絕對沒有直接用“例項名.方法名(引數列表)”來的舒服。

 

我把它放到一個叫WebServiceHelper.cs的類裡面了。

using 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()); 

            

            //生成代理例項,並呼叫方法  

            System.Reflection.Assembly assembly = cr.CompiledAssembly; 

            Type t = assembly.GetType(@namespace + "." + classname, true, true); 

            object obj = Activator.CreateInstance(t); 

            System.Reflection.MethodInfo mi = t.GetMethod(methodname); 

            return mi.Invoke(obj, args); 

        

   

        private static string GetClassName(string url) 

        

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

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

            return pps[0];