動態呼叫WebService C

2021-06-14 09:57:18 字數 3451 閱讀 3706

通常我們在程式中需要呼叫webservice時,都是通過「新增web引用」,讓vs.net環境來為我們生成服務**,然後呼叫對應的web服務。這樣是使工作簡單了,但是卻和提供web服務的url、方法名、引數繫結在一起了,這是vs.net自動為我們生成web服務**的限制。如果哪一天發布web服務的url改變了,則我們需要重新讓vs.net生成**,並重新編譯。在某些情況下,這可能是不能忍受的,我們需要動態呼叫webservice的能力。比如我們可以把web服務的url儲存在配置檔案中,這樣,當服務url改變時,只需要修改配置檔案就可以了。 

說了這麼多,實際上我們要實現這樣的功能: 

public static object invokewebservice(string url,  string methodname, object args)

其中,url是web服務的位址,methodname是要呼叫服務方法名,args是要呼叫web服務所需的引數,返回值就是web服務返回的結果了。 

要實現這樣的功能,你需要這幾個方面的技能:反射、codedom、程式設計使用c#編譯器、webservice。在了解這些知識後,就可以容易的實現web服務的動態呼叫了: 

using system.codedom.compiler;

using system;

using system.net;

using system.codedom;

using microsoft.csharp;

using system.io;

using system.web.services.description;

using system.collections.generic;

using system.reflection;

namespace cjl.webservices

static type gettypefromcache(string url, string classname)

}return null;

}static type gettypefromwebservice(string url, string classname)

//獲取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)

throw new exception(sb.tostring());

}//生成**例項,並呼叫方法

system.reflection.assembly assembly = cr.compiledassembly;

type t = assembly.gettype(@namespace + "." + classname, true, true);

return t;

}//動態呼叫web服務

public static object invokewebservice(string url, string methodname, object args)

public static object invokewebservice(string url, string classname, string methodname, object args)

object obj = activator.createinstance(t);

methodinfo mi = t.getmethod(methodname);

return mi.invoke(obj, args);

}catch (exception ex)

}private static string getwsclassname(string wsurl)

#endregion

}}

上面的注釋已經很好的說明了各**段的功能,下面給個例子看看,這個例子是通過訪問

服務來獲取各大城市的天氣狀況。

string url = "";

string args = new string[2];

args[0] = this.textbox_cityname.text;

args[1] = "china";

object result = webservicehelper.invokewebservice(url, "getweather", args);

this.label_result.text = result.tostring();

上述的例子中,呼叫web服務使用了兩個引數,第乙個是城市的名字,第二個是國家的名字,web服務返回的是xml文件,可以從其中解析出溫度、風力等天氣情況。 

最後說一下,c#雖然仍屬於靜態語言之列,但是其動態能力也是很強大的,不信,你可以看看spring.net的aop實現,這種「無侵入」的aop實現比通常的.net宣告式aop實現(一般是通過aop attribute)要漂亮的多。

動態呼叫WebService C

通常我們在程式中需要呼叫webservice時,都是通過 新增web引用 讓vs.net環境來為我們生成服務 然後呼叫對應的web服務。這樣是使工作簡單了,但是卻和提供web服務的url 方法名 引數繫結在一起了,這是vs.net自動為我們生成web服務 的限制。如果哪一天發布web服務的url改變...

動態呼叫WebService C

通常我們在程式中需要呼叫webservice時,都是通過 新增web引用 讓vs.net環境來為我們生成服務 然後呼叫對應的web服務。這樣是使工作簡單了,但是卻和提供web服務的url 方法名 引數繫結在一起了,這是vs.net自動為我們生成web服務 的限制。如果哪一天發布web服務的url改變...

動態呼叫WebService C

通常我們在程式中需要呼叫webservice時,都是通過 新增web引用 讓vs.net環境來為我們生成服務 然後呼叫對應的web服務。這樣是使工作簡單了,但是卻和提供web服務的url 方法名 引數繫結在一起了,這是vs.net自動為我們生成web服務 的限制。如果哪一天發布web服務的url改變...