共用方式為


將 Web 服務公開給用戶端指令碼

更新:2007 年 11 月

ASP.NET 的 AJAX 功能可讓您使用用戶端指令碼,從瀏覽器呼叫 ASP.NET Web 服務 (.asmx 檔案)。這麼做可以改善 Web 應用程式的使用者經驗。這個頁面可以呼叫伺服器端方法,不需回傳也不需重新整理整個頁面,因為只有資料才會在瀏覽器和 Web 伺服器之間傳輸。

本主題描述如何讓在瀏覽器中執行的 JavaScript 使用 Web 服務。

ASP.NET 會為 Web 服務自動建立 JavaScript Proxy 類別。Proxy 類別是衍生自 Sys.Net.WebServiceProxy 類別。您可以呼叫 JavaScript Proxy 類別對應的方法,藉此呼叫 Web 服務方法。如需詳細資訊,請參閱從用戶端指令碼呼叫 Web 服務

使 Web 服務可從指令碼存取

若要讓 Web 服務能夠從指令碼存取,它必須是 .asmx Web 服務,而且其 Web 服務類別是以 ScriptServiceAttribute 屬性限定。要從指令碼呼叫的個別方法必須以 WebMethodAttribute 屬性限定。

下列範例顯示 Web 服務程式碼中的這些屬性。

[ScriptService]
public class SimpleWebService : System.Web.Services.WebService
{
    [WebMethod]
    public string EchoInput(String input)
    {
        // Method code goes here.
    }
}

<ScriptService> _
Public Class SimpleWebService
        Inherits System.Web.Services.WebService
    <WebMethod> _
    Public Function EchoInput(ByVal input As String) As String
        ' Method code goes here.
    End Function
End Class

若要讓 Web 服務可從指令碼呼叫,您必須在應用程式的 Web.config 檔案中註冊 ScriptHandlerFactory HTTP 處理常式。這個處理常式會處理指令碼對 .asmx Web 服務的呼叫。下列範例示範 Web.config 項目以加入處理常式。

注意事項:

對於您在 Microsoft Visual Studio 2005 中所建立之任何新的具備 AJAX 能力的網站,這些組態設定已是 Web.config 檔案範本的一部分。

<system.web>
  <httpHandlers>
    <remove verb="*" path="*.asmx"/> 
    <add verb="*" path="*.asmx" 
      type="System.Web.Script.Services.ScriptHandlerFactory"
       validate="false"/>
  </httpHandlers>
<system.web>

對於不是從 ASP.NET AJAX 指令碼發出的 Web 服務呼叫,ScriptHandlerFactory 處理常式會將呼叫委派給使用 SOAP (不是 JSON) 格式的預設處理常式。委派會自動執行,除非您要將 Web 服務的 SOAP 通訊協定停用,否則便不需採取任何動作。如果是這樣,您就必須在 Web.config 檔案中輸入下列組態設定。

<system.web>
  <webServices>    <protocols>      <clear/>    </protocols>  </webServices>
</system.web>

在 ASP.NET 網頁中向用戶端指令碼公開 Web 服務

若要從 ASP.NET 網頁中的用戶端指令碼呼叫 .asmx Web 服務,您必須將 ScriptManager 控制項加入頁該頁面。您可以將 asp:ServiceReference 子項目加入至 ScriptManager 控制項,然後將伺服器參考 path 屬性設定為 Web 服務的 URL,以參考 Web 服務。ServiceReference 物件會指示 ASP.NET 產生 JavaScript Proxy 類別,從用戶端指令碼呼叫指定的 Web 服務。

下列範例示範如何從 ASP.NET 網頁中的指令碼呼叫名為 SimpleWebService.asmx 的 Web 服務。

<asp:ScriptManager  ID="scriptManager">
  <Services>
    <asp:ServiceReference
       path="~/WebServices/SimpleWebService.asmx" />
  </Services>
</asp:ScriptManager>

ServiceReference 物件只能參考與頁面同一網域中的 Web 服務。Web 服務路徑可以是相對路徑、應用程式的相對路徑、網域的相對路徑或絕對路徑。如果是絕對路徑,您必須確定路徑在同一個網域中。

當內含這個 ScriptManager 控制項的頁面呈現時,該頁面會建立一個 SimpleWebService.asmx Web 服務的 JavaScript Proxy 類別。Proxy 類別具有的方法,會對應於 SimpleWebService.asmx 服務中的 Web 方法。這個頁面也包含 JavaScript Proxy 類別,所對應的伺服器資料型別是做為 Web 服務方法的輸入參數或傳回值。可讓您撰寫會初始化這些參數的用戶端指令碼,並將參數傳遞給方法呼叫。

ServiceReference 物件的 InlineScript 屬性會指定 JavaScript Proxy 類別如何包含在頁面中。如果 InlineScript 設定為 false (預設),則執行個別要求就會取得 Proxy 指令碼。當多個頁面參考同一個服務,以及瀏覽器快取為啟用時,則使用這個選項較好。

如果 InlineScript 設定為 true,則 Proxy 類別指令碼會包含在頁面中做為內嵌指令碼區塊。這麼做會減少網路要求的次數以提高效能。特別是如果頁面中有許多服務參考,而且其他頁面不會參考相同服務時更是如此。如果 InlineScript 設定為 true,您必須使用相對路徑。如果路徑為網域相對路徑,就必須參考相同的 Web 應用程式。

下列範例示範一個從指令碼呼叫的簡單 Web 服務,會顯示使用者的輸入並傳回目前的伺服器時間。下列範例示範透過用戶端指令碼呼叫服務的頁面。

<%@ Page Language="VB" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

    <head id="Head1" >
        <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }

            .text { font: 8pt Trebuchet MS }
        </style>

        <title>Simple Web Service</title>

            <script type="text/javascript">

            // This function calls the Web Service method.  
            function EchoUserInput()
            {
                var echoElem = document.getElementById("EnteredValue");
                Samples.AspNet.SimpleWebService.EchoInput(echoElem.value,
                    SucceededCallback);
            }

            // This is the callback function that
            // processes the Web Service return value.
            function SucceededCallback(result)
            {
                var RsltElem = document.getElementById("Results");
                RsltElem.innerHTML = result;
            }

        </script>

    </head>

    <body>
        <form id="Form1" >
         <asp:ScriptManager  ID="scriptManager">
                <Services>
                    <asp:ServiceReference path="SimpleWebService_VB.asmx" />
                </Services>
            </asp:ScriptManager>
            <div>
                <h2>Simple Web Service</h2>
                    <p>Calling a simple service that echoes the user's input and 
                        returns the current server time.</p>
                    <input id="EnteredValue" type="text" />
                    <input id="EchoButton" type="button" 
                        value="Echo" onclick="EchoUserInput()" />
            </div>
        </form>

        <hr/>

        <div>
            <span id="Results"></span>
        </div>   

    </body>

</html>
<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

    <head id="Head1" >
        <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }

            .text { font: 8pt Trebuchet MS }
        </style>

        <title>Simple Web Service</title>

            <script type="text/javascript">

            // This function calls the Web Service method.  
            function EchoUserInput()
            {
                var echoElem = document.getElementById("EnteredValue");
                Samples.AspNet.SimpleWebService.EchoInput(echoElem.value,
                    SucceededCallback);
            }

            // This is the callback function that
            // processes the Web Service return value.
            function SucceededCallback(result)
            {
                var RsltElem = document.getElementById("Results");
                RsltElem.innerHTML = result;
            }

        </script>

    </head>

    <body>
        <form id="Form1" >
         <asp:ScriptManager  ID="scriptManager">
                <Services>
                    <asp:ServiceReference path="SimpleWebService.asmx" />
                </Services>
            </asp:ScriptManager>
            <div>
                <h2>Simple Web Service</h2>
                    <p>Calling a simple service that echoes the user's input and 
                        returns the current server time.</p>
                    <input id="EnteredValue" type="text" />
                    <input id="EchoButton" type="button" 
                        value="Echo" onclick="EchoUserInput()" />
            </div>
        </form>

        <hr/>

        <div>
            <span id="Results"></span>
        </div>   

    </body>

</html>

下列範例示範透過用戶端指令碼呼叫的服務。

<%@ WebService Language="VB" Class="Samples.AspNet.SimpleWebService" %>

Imports System.Web
Imports System.Web.Services
Imports System.Xml
Imports System.Web.Services.Protocols
Imports System.Web.Script.Services

Namespace Samples.AspNet

    <WebService(Namespace:="http://tempuri.org/")> _
    <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
    <ScriptService()> _
    Public Class SimpleWebService
    Inherits System.Web.Services.WebService

    <WebMethod()>  _
    Public Function EchoInput(ByVal input As String) As String 
        Dim inputString As String = Server.HtmlEncode(input)
        If Not String.IsNullOrEmpty(inputString) Then
                Return String.Format("You entered {0}. The " + _
                "current time is {1}.", inputString, DateTime.Now)
        Else
            Return "The input string was null or empty."
        End If

    End Function 'EchoInput
End Class 'SimpleWebService 

End Namespace
<%@ WebService Language="C#" Class="Samples.AspNet.SimpleWebService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Web.Services.Protocols;
using System.Web.Script.Services;

namespace Samples.AspNet
{

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ScriptService]
    public class SimpleWebService : System.Web.Services.WebService
    {

        [WebMethod]
        public string EchoInput(String input)
        {
            string inputString = Server.HtmlEncode(input);
            if (!String.IsNullOrEmpty(inputString))
            {
                return String.Format("You entered {0}. The "
                  + "current time is {1}.", inputString, DateTime.Now);
            }
            else
            {
                return "The input string was null or empty.";
            }
        }

    }

}

在 ASP.NET 網頁中呼叫靜態方法

您可以將靜態網頁方法加入至 ASP.NET 網頁,並將這些方法限定為 Web 方法。然後您就可以從該頁面的指令碼呼叫這些方法,就像是 Web 服務的一部分,但是不必建立個別 .asmx 檔案。若要在網頁中建立 Web 方法,請匯入 System.Web.Services 命名空間,並將 WebMethodAttribute 屬性加入至要公開的每個靜態方法。頁面方法必須定義於執行頁面方法呼叫的頁面中。

若要將靜態頁面方法當做 Web 方法來呼叫,您必須將 ScriptManager 控制項的 EnablePageMethods 屬性設定為 true。

下列範例示範如何從用戶端指令碼呼叫靜態頁面方法,以讀取和寫入工作階段狀態值。下列範例顯示頁面方法。

<%@ Page Language="VB" %>
<%@ Import Namespace="System.Web.Services" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<script >

    <WebMethod()> _
    Public Shared Function GetSessionValue(ByVal key As String) As String
        ' Get session state value.
        Return CStr(HttpContext.Current.Session(key))

    End Function 'GetSessionValue


    <WebMethod()> _
    Public Shared Function SetSessionValue(ByVal key As String, _
    ByVal value As String) As String
        ' Set session state value.
        HttpContext.Current.Session(key) = value
        Return CStr(HttpContext.Current.Session(key))

    End Function 'SetSessionValue

</script>

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" >

    <title>Using Page Methods with Session State</title>
    <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }
            .text { font: 8pt Trebuchet MS }
    </style>
</head>

<body>

    <h2>Using Page Methods with Session State</h2>

    <form id="form1" >
        <asp:ScriptManager ID="ScriptManager1" 
             EnablePageMethods="true">
            <Scripts>
                <asp:ScriptReference Path="PageMethod.js"/>
            </Scripts>
        </asp:ScriptManager>
    </form>

     <center>
         <table>
            <tr align="left">
                <td>Write current date and time in session state:</td>
                <td>
                    <input type="button" 
                        onclick="SetSessionValue('SessionValue', Date())" 
                        value="Write" />
                </td>
            </tr>
            <tr align="left">
                <td>Read current date and time from session state:</td>
                <td>         
                    <input type="button" 
                        onclick="GetSessionValue('SessionValue')" 
                        value="Read" />
                </td>
            </tr>
        </table>           
    </center>

    <hr/>

    <span style="background-color:Aqua" id="ResultId"></span>

</body>

</html>
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Web.Services" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<script >

    [WebMethod]
    // Get session state value.
    public static string GetSessionValue(string key)
    {
        return (string)HttpContext.Current.Session[key];
    }

    [WebMethod]
    // Set session state value.
    public static string SetSessionValue(string key, string value)
    {
        HttpContext.Current.Session[key] = value;
        return (string)HttpContext.Current.Session[key];
    }

</script>

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" >

    <title>Using Page Methods with Session State</title>
    <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }
            .text { font: 8pt Trebuchet MS }
    </style>
</head>

<body>

    <h2>Using Page Methods with Session State</h2>

    <form id="form1" >
        <asp:ScriptManager ID="ScriptManager1" 
             EnablePageMethods="true">
            <Scripts>
                <asp:ScriptReference Path="PageMethod.js"/>
            </Scripts>
        </asp:ScriptManager>
    </form>

     <center>
         <table>
            <tr align="left">
                <td>Write current date and time in session state:</td>
                <td>
                    <input type="button" 
                        onclick="SetSessionValue('SessionValue', Date())" 
                        value="Write" />
                </td>
            </tr>
            <tr align="left">
                <td>Read current date and time from session state:</td>
                <td>         
                    <input type="button" 
                        onclick="GetSessionValue('SessionValue')" 
                        value="Read" />
                </td>
            </tr>
        </table>           
    </center>

    <hr/>

    <span style="background-color:Aqua" id="ResultId"></span>

</body>

</html>

下列範例示範用於呼叫頁面方法的指令碼。

// PageMethods.js

var displayElement;

// Initializes global variables and session state.
function pageLoad()
{
    displayElement = $get("ResultId");
    PageMethods.SetSessionValue("SessionValue", Date(), 
        OnSucceeded, OnFailed);
}

// Gets the session state value.
function GetSessionValue(key) 
{
    PageMethods.GetSessionValue(key, 
        OnSucceeded, OnFailed);
}

//Sets the session state value.
function SetSessionValue(key, value) 
{
    PageMethods.SetSessionValue(key, value, 
        OnSucceeded, OnFailed);
}

// Callback function invoked on successful 
// completion of the page method.
function OnSucceeded(result, userContext, methodName) 
{
    if (methodName == "GetSessionValue")
    {
        displayElement.innerHTML = "Current session state value: " + 
            result;
    }
}

// Callback function invoked on failure 
// of the page method.
function OnFailed(error, userContext, methodName) 
{
    if(error !== null) 
    {
        displayElement.innerHTML = "An error occurred: " + 
            error.get_message();
    }
}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

如需工作階段狀態的詳細資訊,請參閱 ASP.NET 工作階段狀態概觀

請參閱

工作

搭配 Web 服務使用 UpdatePanel 控制項

概念

在 ASP.NET AJAX 中使用 Web 服務

在 ASP.NET AJAX 中使用 Web 服務

將 WCF 服務公開給用戶端指令碼

從用戶端指令碼呼叫 Web 服務

搭配 ASP.NET AJAX 使用表單驗證

搭配 ASP.NET AJAX 使用設定檔資訊