Esposizione di servizi Web a script client

Aggiornamento: novembre 2007

La funzionalità AJAX di ASP.NET consente di chiamare i servizi Web ASP.NET (file ASMX) dal browser tramite script client. Ciò consente di migliorare l'esperienza utente per l'applicazione Web. La pagina può chiamare metodi basati su server senza alcun postback e senza aggiornare l'intera pagina, poiché solo i dati vengono trasferiti tra il browser e il server Web.

In questo argomento viene descritto come rendere disponibile un servizio Web per JavaScript eseguito nel browser.

ASP.NET crea automaticamente classi proxy JavaScript per i servizi Web. Le classi proxy derivano dalla classe Sys.Net.WebServiceProxy. Per chiamare un metodo del servizio Web, è possibile chiamare il metodo corrispondente della classe proxy JavaScript. Per ulteriori informazioni, vedere Chiamata a servizi Web da script client.

Accessibilità dei servizi Web da script

Un servizio Web accessibile da script deve essere un servizio Web ASMX la cui classe è qualificata con l'attributo ScriptServiceAttribute. I singoli metodi da chiamare da script devono essere qualificati con l'attributo WebMethodAttribute.

Nell'esempio seguente vengono illustrati questi attributi nel codice del servizio 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

Per consentire le chiamate al servizio Web da script, è necessario registrare il gestore HTTP ScriptHandlerFactory nel file Web.config dell'applicazione. Il gestore elabora le chiamate eseguite da script ai servizi Web ASMX. Nell'esempio riportato di seguito viene illustrato l'elemento Web.config per l'aggiunta del gestore.

Nota:

Nei nuovi siti Web con supporto AJAX creati in Microsoft Visual Studio 2005, queste impostazioni di configurazione appartengono già al modello del file Web.config.

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

Per le chiamate al servizio Web che non vengono emesse da script ASP.NET AJAX, il gestore ScriptHandlerFactory delega la chiamata al gestore predefinito, il quale utilizza il formato SOAP anziché il formato JSON. La delega viene eseguita automaticamente e non sarà necessaria alcuna operazione particolare, a meno che non si voglia disattivare l'utilizzo del protocollo SOAP per i servizi Web. In tal caso, è necessario immettere la seguente impostazione di configurazione nel file Web.config.

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

Esposizione dei servizi Web a script client in una pagina Web ASP.NET

Per consentire la chiamata a un servizio Web ASMX da script client in una pagina Web ASP.NET, è necessario aggiungere un controllo ScriptManager alla pagina. Per fare riferimento al servizio Web, aggiungere un elemento figlio asp:ServiceReference al controllo ScriptManager, quindi impostare l'attributo path del riferimento al server sull'URL del servizio Web. L'oggetto ServiceReference indica ad ASP.NET di generare una classe proxy JavaScript per la chiamata al servizio Web specificato da script client.

Nell'esempio seguente viene illustrato come abilitare la chiamata a un servizio Web denominato SimpleWebService.asmx da script in una pagina Web ASP.NET.

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

L'oggetto ServiceReference può fare unicamente riferimento a un servizio Web nello stesso dominio della pagina. Il percorso del servizio Web può essere relativo, relativo all'applicazione, relativo al dominio o assoluto. Nel caso dei percorsi assoluti, è necessario assicurarsi che il percorso si trovi nello stesso dominio.

Quando viene eseguito il rendering di una pagina contenente questo controllo ScriptManager, la pagina crea una classe proxy JavaScript per il servizio Web SimpleWebService.asmx. La classe proxy possiede metodi che corrispondono ai metodi Web nel servizio SimpleWebService.asmx. La pagina contiene anche classi proxy JavaScript corrispondenti ai tipi di dati del server utilizzati come parametri di input o valori restituiti per i metodi del servizio Web. Ciò consente di scrivere script client che inizializza questi parametri e di passare tali parametri alla chiamata al metodo.

La proprietà InlineScript dell'oggetto ServiceReference specifica il modo in cui la classe proxy JavaScript viene inclusa nella pagina. Se InlineScript è impostato su false (impostazione predefinita), lo script proxy è ottenuto tramite una richiesta separata. Questa opzione è preferibile nel caso in cui più pagine fanno riferimento allo stesso servizio e la memorizzazione nella cache del browser è attivata.

Se InlineScript è impostato su true, lo script della classe proxy viene incluso nella pagina sotto forma di blocco di script in linea. In questo modo è possibile migliorare le prestazioni, riducendo il numero delle richieste di rete. Questo accade in particolare se vi sono molti riferimenti al servizio nella pagina e le altre pagine non fanno riferimento allo stesso servizio. Se InlineScript è impostato su true, è necessario utilizzare un percorso relativo. Se il percorso è relativo al dominio, deve fare riferimento alla stessa applicazione Web.

Negli esempi seguenti viene illustrato un servizio Web semplice chiamato da script che visualizza l'input dell'utente e restituisce l'ora del server corrente. Nell'esempio riportato di seguito viene illustrata la pagina che esegue chiamate al servizio tramite script client.

<%@ 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>

Nell'esempio riportato di seguito viene illustrato il servizio chiamato tramite lo script client.

<%@ 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.";
            }
        }

    }

}

Chiamata a metodi statici in una pagina Web ASP.NET

È possibile aggiungere metodi statici a una pagina ASP.NET e qualificarli come metodi Web. È quindi possibile chiamare questi metodi da script nella stessa pagina come se appartenessero a un servizio Web, ma senza creare un file ASMX separato. Per creare metodi Web in una pagina, importare lo spazio dei nomi System.Web.Services e aggiungere un attributo WebMethodAttribute a ogni metodo statico che si desidera esporre. Tali metodi devono essere definiti nella pagina che esegue la chiamata al metodo.

Affinché sia possibile chiamare metodi statici come metodi Web, è necessario impostare l'attributo EnablePageMethods del controllo ScriptManager su true.

Negli esempi seguenti viene illustrato come chiamare metodi statici da script client per la lettura e scrittura dei valori dello stato sessione. Nell'esempio che segue vengono illustrati i metodi della pagina.

<%@ 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>

Nell'esempio che segue viene illustrato lo script utilizzato per effettuare le chiamate ai metodi della pagina.

// 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();

Per ulteriori informazioni sullo stato sessione, vedere Cenni preliminare sullo stato della sessione ASP.NET.

Vedere anche

Attività

Utilizzo del controllo UpdatePanel con un servizio Web

Concetti

Utilizzo dei servizi Web in ASP.NET AJAX

Utilizzo dei servizi Web in ASP.NET AJAX

Esposizione di servizi WCF a script client

Chiamata a servizi Web da script client

Utilizzo dell'autenticazione basata su form con ASP.NET AJAX

Utilizzo delle informazioni sul profilo con ASP.NET AJAX