如何动态调用WebServices
但是,如果我們不想通過添加引用的方式,而是在代碼中動態(tài)引用該怎么辦呢?
首先,我們該想到WS的實現(xiàn)也是一個類的形式。
其次,WS在傳輸過程中是通過WSDL來進行描述的(使用SOAP協(xié)議)。
因此,我們需要獲取WS的WSDL描述,并通過該描述來動態(tài)生成程序集。
最后:通過反射來獲取新生成的程序集,并調(diào)用其方法!
上述步驟需要引用如下四個名稱空間:
using?System.Web.Services.Description;? //WS的描述
//以下幾個用于根據(jù)描述動態(tài)生成代碼并動態(tài)編譯獲取程序集
using?System.CodeDom;?
using?Microsoft.CSharp;
using?System.CodeDom.Compiler;
上述幾個名稱空間中包括如下幾個重要的類:
using?System.Web.Services.Description下:
ServiceDescription? //WS描述
ServiceDescriptionImporter? //通過描述生成客戶端代理類,特別注意其中的Style
以下是MSDN對其的描述:
??????? XML Web services 的接口通常由 Web 服務(wù)描述語言 (WSDL) 文件來說明。例如,若要獲取有關(guān)使用 http://localhost/service.asmx 處公開的 ASP.NET 的 Web 服務(wù)的 WSDL 說明,只需導航到 http://localhost/service.asmx?WSDL。使用 ServiceDescriptionImporter 類可以方便地將 WSDL 說明中包含的信息導入到 <?XML:NAMESPACE PREFIX = MSHelp NS = "http://msdn.microsoft.com/mshelp" /> 對象。通過調(diào)整 Style 參數(shù)的值,可以指示 ServiceDescriptionImporter 實例生成客戶端代理類(通過透明調(diào)用該類可提供 Web 服務(wù)的功能)或生成抽象類(該類封裝 Web 服務(wù)的功能而不實現(xiàn)該功能)。如果將 Style 屬性設(shè)置為 Client,則 ServiceDescriptionImporter 生成客戶端代理類,通過調(diào)用這些類來提供說明的 Web 服務(wù)的功能。如果將 Style 屬性設(shè)置為 ,則 ServiceDescriptionImporter 實例生成抽象類,這些類表示所說明的 XML Web services 的功能而不進行實現(xiàn)。然后,可以通過編寫從這些抽象類繼承的類來對其進行實現(xiàn),并實現(xiàn)相關(guān)的方法。
using?System.CodeDom下:
?CodedomUnit //它用于設(shè)定動態(tài)代碼的名稱空間,類名等,可以通過ServiceDescriptionImporter.Import()方法將WS的描述代碼寫入該類,以作動態(tài)編譯用
using?System.CodeDom.Compiler下:
CodedomProvider //用于創(chuàng)建和檢索代碼生成器和代碼編譯器的實例,我們主要用到其實現(xiàn)子類CShareCodeProvider
可以直接用CShareCodeProvider provider=new CShareCodeProvider()來生成,或者用CodedomProvider.CreateProvider("CSharp")來生成
ICodeCompiler //用于編譯基于 System.CodeDom 的源代碼表示形式。
它通過CodedomProvider的CreateCompiler()方法來
CompilerResults? //表示從編譯器返回的編譯結(jié)果。 它由ICodeCompiler根據(jù)指定的編譯器設(shè)置從指定的 CodeCompileUnit 所包含的 System.CodeDom 樹中編譯程序集并返回。CompiledAssembly 屬性指示編譯的程序集。
了解如上信息后,就可動態(tài)調(diào)用WS了。
如下是摘自http://www.cnblogs.com/ruochen/archive/2007/12/11/990427.html的代碼演示:
?1using?System;
?2using?System.Collections.Generic;
?3using?System.Text;
?4using?System.Net;
?5using?System.IO;
?6using?System.Web.Services.Description;
?7using?System.CodeDom;
?8using?Microsoft.CSharp;
?9using?System.CodeDom.Compiler;
10
11namespace?TestSkin
12{
13????class?Webservices
14????{
15????????/**////?<summary>
16????????///?實例化WebServices
17????????///?</summary>
18????????///?<param?name="url">WebServices地址</param>
19????????///?<param?name="methodname">調(diào)用的方法</param>
20????????///?<param?name="args">把webservices里需要的參數(shù)按順序放到這個object[]里</param>
21????????public?static?object?InvokeWebService(string?url,?string?methodname,?object[]?args)
22????????{
23
24????????????//這里的namespace是需引用的webservices的命名空間,在這里是寫死的,大家可以加一個參數(shù)從外面?zhèn)鬟M來。
25????????????string?@namespace?=?"client";
26????????????try
27????????????{
28????????????????//獲取WSDL
29????????????????WebClient?wc?=?new?WebClient();
30????????????????Stream?stream?=?wc.OpenRead(url?+?"?WSDL");
31????????????????ServiceDescription?sd?=?ServiceDescription.Read(stream);
32????????????????string?classname?=?sd.Services[0].Name;
33????????????????ServiceDescriptionImporter?sdi?=?new?ServiceDescriptionImporter();
34????????????????sdi.AddServiceDescription(sd,?"",?"");
35????????????????CodeNamespace?cn?=?new?CodeNamespace(@namespace);
36
37????????????????//生成客戶端代理類代碼
38????????????????CodeCompileUnit?ccu?=?new?CodeCompileUnit();
39????????????????ccu.Namespaces.Add(cn);
40????????????????sdi.Import(cn,?ccu);
41????????????????CSharpCodeProvider?csc?=?new?CSharpCodeProvider();
42????????????????ICodeCompiler?icc?=?csc.CreateCompiler();
43
44????????????????//設(shè)定編譯參數(shù)
45????????????????CompilerParameters?cplist?=?new?CompilerParameters();
46????????????????cplist.GenerateExecutable?=?false;
47????????????????cplist.GenerateInMemory?=?true;
48????????????????cplist.ReferencedAssemblies.Add("System.dll");
49????????????????cplist.ReferencedAssemblies.Add("System.XML.dll");
50????????????????cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
51????????????????cplist.ReferencedAssemblies.Add("System.Data.dll");
52
53????????????????//編譯代理類
54????????????????CompilerResults?cr?=?icc.CompileAssemblyFromDom(cplist,?ccu);
55????????????????if?(true?==?cr.Errors.HasErrors)
56????????????????{
57????????????????????System.Text.StringBuilder?sb?=?new?System.Text.StringBuilder();
58????????????????????foreach?(System.CodeDom.Compiler.CompilerError?ce?in?cr.Errors)
59????????????????????{
60????????????????????????sb.Append(ce.ToString());
61????????????????????????sb.Append(System.Environment.NewLine);
62????????????????????}
63????????????????????throw?new?Exception(sb.ToString());
64????????????????}
65
66????????????????//生成代理實例,并調(diào)用方法
67????????????????System.Reflection.Assembly?assembly?=?cr.CompiledAssembly;
68????????????????Type?t?=?assembly.GetType(@namespace?+?"."?+?classname,?true,?true);
69????????????????object?obj?=?Activator.CreateInstance(t);
70????????????????System.Reflection.MethodInfo?mi?=?t.GetMethod(methodname);
71
72????????????????return?mi.Invoke(obj,?args);
73????????????}
74????????????catch
75????????????{
76????????????????return?null;
77????????????}
78????????}
79????}
80}
===了解上述類和方法后,基本就可以動態(tài)調(diào)用WS了。
特別注意的是:動態(tài)編譯后需要用到反射來讀取并執(zhí)行。因此需要您了解什么是反射及如何反射
轉(zhuǎn)載于:https://www.cnblogs.com/McJeremy/archive/2008/11/10/1330463.html
總結(jié)
以上是生活随笔為你收集整理的如何动态调用WebServices的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在windows 2008下不同域活动目
- 下一篇: 中国湖泊