我們都知道,調(diào)用WebService可以在工程中對(duì)WebService地址進(jìn)行WEB引用,但是這確實(shí)很不方便。我想能夠利用配置文件靈活調(diào)用WebService。如何實(shí)現(xiàn)呢?
用C#通過(guò)反射實(shí)現(xiàn)動(dòng)態(tài)調(diào)用WebService
上代碼,先試再說(shuō):
using System;using System.Collections.Generic;using System.Text;using System.Net;using System.IO;using System.Web.Services.Description;using System.CodeDom;using Microsoft.CSharp;using System.CodeDom.Compiler;namespace TestCommon{ public class Webservice { /// <summary> /// 實(shí)例化WebServices /// </summary> /// <param name="url">WebServices地址</param> /// <param name="methodname">調(diào)用的方法</param> /// <param name="args">把webservices里需要的參數(shù)按順序放到這個(gè)object[]里</param> public static object InvokeWebService(string url, string methodname, object[] args) { //這里的namespace是需引用的webservices的命名空間,我沒(méi)有改過(guò),也可以使用。也可以加一個(gè)參數(shù)從外面?zhèn)鬟M(jìn)來(lái)。 string @namespace = "client"; try { //獲取WSDL WebClient wc = new WebClient(); Stream stream = wc.OpenRead(url + "?WSDL"); ServiceDescription sd = ServiceDescription.Read(stream); string classname = sd.Services[0].Name; ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(@namespace); //生成客戶(hù)端代理類(lèi)代碼 CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); CSharpCodePRovider csc = new CSharpCodeProvider(); //ICodeCompiler icc = csc.CreateCompiler(); //設(shè)定編譯參數(shù) 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"); //編譯代理類(lèi) CompilerResults cr = csc.CompileAssemblyFromDom(cplist, ccu); if (true == cr.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) { sb.Append(ce.ToString()); sb.Append(System.Environment.NewLine); } throw new Exception(sb.ToString()); } //生成代理實(shí)例,并調(diào)用方法 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); } catch { return null; } } }}
注意:上述代碼需要引用如下四個(gè)名稱(chēng)空間:
using System.Web.Services.Description; //WS的描述
//以下幾個(gè)用于根據(jù)描述動(dòng)態(tài)生成代碼并動(dòng)態(tài)編譯獲取程序集
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
如果你看到這段文字,說(shuō)明您正使用rss閱讀或轉(zhuǎn)自《一棵樹(shù)-博客園》,原文地址:http://www.survivalescaperooms.com/atree/p/WebService_dynamic.html
代碼相對(duì)簡(jiǎn)單,為什么可以如此調(diào)用呢?動(dòng)態(tài)編譯后用反射來(lái)讀取并執(zhí)行。也許了解反射及如何反射對(duì)你會(huì)有幫助。
反射提供了封裝程序集、模塊和類(lèi)型的對(duì)象(Type 類(lèi)型)。可以使用反射動(dòng)態(tài)創(chuàng)建類(lèi)型的實(shí)例,將類(lèi)型綁定到現(xiàn)有對(duì)象,或從現(xiàn)有對(duì)象獲取類(lèi)型并調(diào)用其方法或訪問(wèn)其字段和屬性。詳細(xì)請(qǐng)查看:https://msdn.microsoft.com/zh-cn/library/ms173183(VS.80).aspx
為什么WebServices可以通過(guò)反射實(shí)現(xiàn)?
WebService在傳輸過(guò)程中是通過(guò)WSDL來(lái)進(jìn)行描述的(使用SOAP協(xié)議)。因此,我們需要獲取WebService的WSDL描述,并通過(guò)該描述來(lái)動(dòng)態(tài)生成程序集。然后通過(guò)反射來(lái)獲取新生成的程序集,并調(diào)用其方法!
以下是MSDN對(duì)其的描述:
XML Web services 的接口通常由 Web 服務(wù)描述語(yǔ)言 (WSDL) 文件來(lái)說(shuō)明。例如,若要獲取有關(guān)使用
http://localhost/service.asmx
處公開(kāi)的 asp.net 的 Web 服務(wù)的 WSDL 說(shuō)明,只需導(dǎo)航到http://localhost/service.asmx?WSDL
。使用 ServiceDescriptionImporter 類(lèi)可以方便地將 WSDL 說(shuō)明中包含的信息導(dǎo)入到System.CodeDom.CodeCompileUnit 對(duì)象。通過(guò)調(diào)整 Style 參數(shù)的值,可以指示 ServiceDescriptionImporter 實(shí)例生成客戶(hù)端代理類(lèi)(通過(guò)透明調(diào)用該類(lèi)可提供 Web 服務(wù)的功能)或生成抽象類(lèi)(該類(lèi)封裝 Web 服務(wù)的功能而不實(shí)現(xiàn)該功能)。如果將 Style 屬性設(shè)置為 Client,則 ServiceDescriptionImporter 生成客戶(hù)端代理類(lèi),通過(guò)調(diào)用這些類(lèi)來(lái)提供說(shuō)明的 Web 服務(wù)的功能。如果將 Style 屬性設(shè)置為 Server,則 ServiceDescriptionImporter 實(shí)例生成抽象類(lèi),這些類(lèi)表示所說(shuō)明的 XML Web services 的功能而不進(jìn)行實(shí)現(xiàn)。然后,可以通過(guò)編寫(xiě)從這些抽象類(lèi)繼承的類(lèi)來(lái)對(duì)其進(jìn)行實(shí)現(xiàn),并實(shí)現(xiàn)相關(guān)的方法。
了解更多關(guān)于WebServices的知識(shí):
C#調(diào)用WebService實(shí)例和開(kāi)發(fā)
Web Service 的工作原理
MSDN:https://msdn.microsoft.com/zh-cn/library/system.web.services.webservice(VS.80).aspx
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注