1. 程式人生 > >如何動態呼叫asp.net Webservice

如何動態呼叫asp.net Webservice

摘要:

本文介紹如何在VS2005 IDE中不通過新增web應用來實現webService的動態呼叫。

背景:

你可能會在多種場合遇到這種需求,我能想到有以下兩種,應用這種方法得心應手。

  • 在Application Service Provider Model 中的鬆耦合整合。 Application Service Provider Model 是指單一的web application 可以支援來自不同客戶端的使用者。

在這種情況下,應用程式需要根據不同的客戶來呼叫不同的相互獨立的webService。如果每一個webService都要新增引用,這是一個不大好的注意,尤其在這些service具有相同規範的情況下。

  • 執行時動態呼叫不同的webservice。  假想有兩個或者更多的webservice 他們具有相同的wsdl 用法卻有不同的功能和內部實現,當應用程式需要在執行時依據具體實際需要呼叫相應的服務的時候,這種方法會很有效。

範例

為了簡單起見,我們儘量刪除複雜的邏輯部分。我們省去了餘數據庫互動的程式碼,重點講注意力集中到本文的主題:不新增web引用,呼叫webservice。假設有一個叫WelcomeUser得程式,它符合Application Service Provider這裡的 Model 標準。此程式需要讓來自不同公司 例如"Foo" and "XFoo", 的使用者,登陸進來。

然而,實際的應用程式是web 程式,它通過呼叫部署在Foo and XFoo公司而且進行獨立維護的service實現給不同公司使用者現實不同的歡迎訊息。這個程式的開發著們不想去部署 維護 每個不同客戶端的服務,他們想盡量做到鬆耦合。

儘管只是讓每個公司去寫出自己歡迎訊息的想法聽起來有些小題大作,我們假設這種歡迎資訊是基於兩者公司不同的資料庫環境之上加上覆雜的邏輯處理得到的。

設計WSDL,分佈的客戶端以及他們自身的實現

 由於WelcomeUser 應用程式需要根據不同公司的使用者呼叫不同的webservice,所以開發者應該在寫webservice之前確定下來Foo" and "XFoo 都應該遵守的WSDL規範。

這裡的wsdl 低耦合的契約,類似OOP中的介面。

開發者隨即寫了一個webservice 命名WelcomeMessageStub 包含方法"GetWelcomeMessage()".  示例程式碼如下

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WelcomeMessageStub : System.Web.Services.WebService
{
    public WelcomeMessageStub () { }
    [WebMethod]
    public string GetWelcomeMessage() {
        return "The Welcome Message That You Need To Return";
    }
}

接下來,我們通過訪問"[URL Of the Web Service]/WelcomeMessageStub.asmx?wsdl",  來使用和釋出WSDL 規範Foo" and "XFoo 兩個公司的客戶端。這裡應該指出

有多種工具不需要一定編碼就可以生成WSDL規範。這裡之所以這樣做是想集中精力解決本文開頭提出的問題。

下面我們假設Foo 公司的開發者實現WSDL規範如下編碼:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WelcomeMessageFoo : System.Web.Services.WebService
{
    public WelcomeMessageFoo () { }
    [WebMethod]
    public string GetWelcomeMessage() {
        return "Welcome to Foo!";
    }
}

 xFoo公司開發者則有不同的實現如下

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WelcomeMessageXFoo : System.Web.Services.WebService
{
    public WelcomeMessageXFoo () { }
    [WebMethod]
    public string GetWelcomeMessage() {
        return "Welcome to XFoo User!";
    }
}

假設這兩個不同的webservice 宿主在不同的url 而且他們都遵守Application Service Provider Model 模型。具體來說,來自Foo公司的使用者需要Foo實現的url,而來自

XFOO公司的使用者也需要呼叫自己的url 實現。儘管這個例子非常簡單,但是這是解決方法是通用的,適用於複雜的情況。

完成WelcomeUser應用程式

開始之前,我們來了解一下webservice工作的基本原理和當你在Visual Studio .NET 2005 IDE新增webservice引用時,IDE所做的幕後工作。當你在IDE中設定一個webservice引用時,IDE會為你一個代理類,這個代理類基於WSDL規範,代表了遠端伺服器上的webservice類。如果你曾經對於每次更新webservice引用時,智慧感知就變得不那麼精確

的現象感到困惑,現在就應該知道了那是因為那些關於webservice的智慧感知是V由isual Studio 生成的代理類提供商。當你在client端呼叫webservice的時候,你所做的僅僅是

在本地呼叫代理類的方法而已,代理類實際呼叫遠端Web Service URL的方法。所以每次webservice更新時候 代理類都需要重新生成。然而,通過IDE生成代理類並不是唯一的

方法,,net給我們提供了WSDL.exe 工具可以手動生成代理類。

既然我們已經瞭解了webservice的原理呢IDE所做的處理,就言歸正傳開始寫我們的WelcomeUser 應用程式。首先我們建立WelcomeMessageStub  的代理類。然後使用代理類

呼叫Foo and xFoo 各自的url。

使用WSDL.exe 工具在命令列中如下操作

 

說明一點,WSDL.exe 是基於WSDL 規範生成的WelcomeMessageStub.cs。完成之後,我們快速建立一個website,把程式碼放到App_Code 目錄下。

到此也許我們應該去剖析一下這個生成的代理類程式碼啦。為了集中精力解決問題,我們只是簡單看一下如下程式碼即可。


public WelcomeMessageStub<CODE>()</CODE> {
    this.Url = "http://localhost/WelcomeMessageStub/WelcomeMessageStub.asmx";
}
值得一提的是,這個預設的建構函式包含了webservice宿主的url。但是這個url是可以在執行時動態改變的。下面的程式碼片段展示了Foo and xFoo 客戶端如何

動態呼叫代理類、
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        // We Can use Database or other Mechanisms to select which company
        // the user belongs to. Once this
        // is done we can have a small IF construct
        // to invoke the right web service from the right URL.
        // Without going into those complications the below code displays how we
        // can call two different Web Services using the same proxy Class.
        WelcomeMessageStub welcomeMessageStub = new WelcomeMessageStub();

        // IF the User Belongs to Foo - Lets Hit Foo's Web Service URL to Invoke
        // the right Web Method on the fly.
        welcomeMessageStub.Url =
           "http://localhost/WelcomeMessageStub/WelcomeMessageFoo.asmx";
        Response.Write(welcomeMessageStub.GetWelcomeMessage());

        Response.Write("<br/>");

        // However IF we found out that the user Belongs
        // too xFoo we could Hit xFoo's Web Service
        // URL to Invoke the right Web Method on the fly.
        // The URLs can be COMPLETELY different as
        // long as they are reachable.
        welcomeMessageStub.Url =
          "http://localhost/WelcomeMessageStub/WelcomeMessagexFoo.asmx";
        Response.Write(welcomeMessageStub.GetWelcomeMessage());
    }
}