轉載:學會使用Web Service下(客戶端訪問)

二、客戶端腳本直接訪問Web Service 

藉助於asp.net ajax異步通信層自動生成的客戶端代理,我們也可以在客戶端JS中使用與服務器端同樣的語法調用定義在服務器端的Web Service的方法!下面我們分兩種情況來分析:


1、客戶端直接調用本地Web Service

默認情況下,asp.net Web Service並沒有提供直接通過客戶端腳本進行訪問的方式,爲了實現這個功能,我們必須藉助於asp.net ajax框架,它爲我們提供了使用JS直接調用本地Web Service完善的支持,所以對於以下的操作,你必須確保已安裝了asp.net ajax框架。下面讓我們看看具體如何實現:

(1)、新建一個asp.net ajax Web站點,然後添加一個Web Service
單擊顯示全圖,Ctrl+滾輪縮放圖片


下面是修改後的Web Service代碼:

複製  保存
<%@ WebService Language="C#" Class="WebService" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = "http://ruihua.cnblogs.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WebService  : System.Web.Services.WebService {
[WebMethod]
public string Hello(string name)
{
return string.Format("Hello,{0}!Current Time is :{1}", name, DateTime.Now.ToString());
}
}


請注意紅色部分,要想使客戶端能夠訪問到Web Service,我們必須爲類添加ScriptService特性(當然,你也可以直接添加到相應的方法上)。這個特性是在asp.net ajax框架的Extension部分定義的。好了,Web Service就已經寫好了,下面看看如何在客戶端調用。

b、新建一個asp.net ajax站點,修改後的前臺代碼如下所示:

複製  保存
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript">
function pageLoad(sender,args)
{
//注意引用方式
            WebService.Hello("Ruihua",onCompleted);
}
//異步調用後執行的回調函數
        function onCompleted(result)
{
$get("result").innerHTML = result;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="http://localhost/WebServiceForJS/WebService.asmx" />
</Services>
</asp:ScriptManager>
<div id="result"></div>
</form>
</body>
</html>


代碼非常簡單,我們只需在ScriptManager中添加對Web Service文件的引用,然後在客戶端腳本中使用[NameSpace].[ClassName].[MethodName][para1,para2,...,callbackFunction]的方式直接調用即可,然後在回調函數中接收值並進一步處理。(注意,測試過程中,請將站點都設置爲Web共享,這樣在引用Web Service的時候就不必考慮到端口號,因爲對於同域內不同端口的訪問JS也是不可以的)。如果一切順利,你將看到如下結果:(注意遊覽地址)
單擊顯示全圖,Ctrl+滾輪縮放圖片


以上是在客戶端訪問本地Web Service的情況,下面讓我們看看客戶端如何訪問遠程Web Service.


2、客戶端訪問遠程Web Service

出於安全性考慮,客戶端JS腳本是不可以直接訪問遠程Web Service的,若想實現這個功能,則必須在本地服務器端提供一個代理,透過這個代理進行訪問。下面我們以訪問http://www.webxml.com.cn/WebServices/WeatherWebService.asmx爲例來說明。具體可採取以下兩種方式:

a、通過本地Web Service中轉

實現思路:服務器端建立一個Web Service,然後在相應的方法中調用遠程Web Service的方法,客戶端腳本直接訪問本地Web Service中方法。

主要代碼:

複製  保存
<%@ WebService Language="C#" Class="WebService" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = "http://ruihua.cnblogs.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WebService  : System.Web.Services.WebService {
[WebMethod]
public string[] GetWeatherbyCityName(string theCityName)
{
WeatherForcast.WeatherWebService ws = new WeatherForcast.WeatherWebService();
return ws.getWeatherbyCityName(theCityName);
}
}


前臺Default.aspx代碼:

複製  保存
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript">
function btnGetWeather_onclick(sender,args)
{
var cityName=$get("tbCityName").value;
WebService.GetWeatherbyCityName(cityName,onCompleted,onFailed);
}
//異步調用後成功後執行的回調函數
        function onCompleted(result)
{
var str = new Sys.StringBuilder();
for(var i=0;i<result.length;i++)
{
str.append(result[i]);
str.append("<br/>");
}
$get("result").innerHTML = str.toString();
}
//異步調用後失敗後執行的回調函數
        function onFailed(error)
{
$get("result").innerHTML = error.get_message();
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="WebService.asmx" />
</Services>
</asp:ScriptManager>
<label id="lblCityName">Please input CityName:</label>
<input id="tbCityName" type="text" />
<input id="btnGetWeather" type="button" value="Get Weather" οnclick="return btnGetWeather_onclick()" />
<div id="result"></div>
</form>
</body>
</html>


運行結果:
單擊顯示全圖,Ctrl+滾輪縮放圖片


下載本示例  
http://files.cnblogs.com/ruihua/webserviceforjs1.rar

b、使用Web Service Bridge

asp.net ajax中Web Service橋的支持位於Futures CTP版本中,所以在使用之前,必須保證計算機安裝了asp.net ajax 的Futures CTP版本。
單擊顯示全圖,Ctrl+滾輪縮放圖片


在網站的Bridges目錄下新建一個WeatherForcase.asbx的XML文件,內容如下:

複製  保存
<?xml version="1.0" encoding="utf-8" ?>
<bridge namespace="Ruihua" className="WeatherForcast">
<proxy type="Microsoft.Web.Preview.Services.BridgeRestProxy" serviceUrl="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getWeatherbyCityName"/>
<method name="getWeatherbyCityName">
<input>
<parameter name="theCityName"/>
</input>
</method>
</bridge>


我們來看一下.asbx文件各標籤:
(1)<Bridge/>:定義該本地代理的命名空間(namespace屬性)和類名(className屬性)。這兩個屬性是代表客戶端調用時使用的命名空間及類名,與遠程Web Service我關。
(2)<proxy/>:聲明該代理的類型,並指定遠程Web Service的URL屬性。注意這裏的URL屬性值的構成:.asmx文件的URL加斜杆和要調用的方法名。
(3)<method/>:定義了遠程Web Service中要調用的方法名稱及參數,注意name屬性應與遠程Web Service中要調用的方法名稱一致。
(4)該標籤中通過<parameter/>子標籤聲明瞭方法的參數。

有幾點需要特別說明一下:
(1)、我在實際使用過程中發現,web Service橋只支持httpGet協議,所以我們需要在Web.config文件中開啓HttpGet方式(默認爲HttpPost)。在<configuration/><system.web/>下添加如下配置:

複製  保存
<webServices>
<protocols>
<add name="HttpGet"/>
</protocols>
</webServices>


(2)如果你使用Futures CTP版本自帶的模板新建了一個支持Web Service橋的站點,你需要手動將<buildProviders>節下的<add>元素的extension屬性中的"*"號去掉,這是Fetures CTP的Bug。
(3)一個Web Service橋文件中僅能代理一個方法,如果你需要訪問多個方法,則需要新建多個Web Service橋。如你在其中寫了多個<proxy>及<method/>,客戶端調用時也只會執行最先的那個代理對應的方法。暫時沒還沒找到其它好的方法。
(4)不能使用asp.net ajax異步通信層的服務器端至客戶端的類型轉換功能,因此我們在客戶端得到的返回類型只能是string類型,從而加大了進一步進行處理的難度。

由於存在以上限制,個人感覺使用web Service橋不如使用本地Web Service中轉方便,或許是asp.net ajax在這方面還不夠成熟吧!

下面是Default.aspx的內容:

複製  保存
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript">
function btnGetWeather_onclick(sender,args)
{
var cityName=$get("tbCityName").value;
Ruihua.WeatherForcast.getWeatherbyCityName({"theCityName":cityName},onCompleted,onFailed);
}
//異步調用後成功後執行的回調函數
        function onCompleted(result)
{
$get("result").innerHTML = result;
}
//異步調用後失敗後執行的回調函數
        function onFailed(error)
{
$get("result").innerHTML = error.get_message();
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="Bridges/WeatherForcase.asbx" />
</Services>
</asp:ScriptManager>
<label id="lblCityName">Please input CityName:</label>
<input id="tbCityName" type="text" />
<input id="btnGetWeather" type="button" value="Get Weather" οnclick="return btnGetWeather_onclick()" />
<div id="result"></div>
</form>
</body>
</html>


以上有兩點需要特別注意:
(1)調用遠程Web方法的參數的書寫方式是採用JSON方式,各個參數需要顯式指明參數名和值,幷包裝爲一個JS對象整體傳入本地代理方法,這與常規調用方式有所不同。
(2)在ScriptManager中添加的是對Web Service橋文件的引用。

在城市名稱中輸入"深圳",下面是運行結果:
單擊顯示全圖,Ctrl+滾輪縮放圖片


下載本示例
http://files.cnblogs.com/ruihua/usewebservicebridge.rar

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章