Exponer servicios web a script de cliente
Actualización: noviembre 2007
La funcionalidad AJAX de ASP.NET permite llamar a los servicios web ASP.NET (archivos .asmx) desde el explorador con script de cliente. Esto mejora la experiencia del usuario en la aplicación web. La página puede llamar a métodos basados en servidor sin una devolución de datos y sin actualizar la página entera, ya que sólo se transfieren datos entre el explorador y el servidor web.
En este tema se muestra cómo permitir que un servicio web está disponible para JavaScript que se ejecute en el explorador.
ASP.NET crea automáticamente clases de proxy de JavaScript para los servicios web. Las clases de proxy se derivan de la clase Sys.Net.WebServiceProxy. Para llamar a un método del servicio web, llama al método correspondiente de la clase de proxy de JavaScript. Para obtener más información, consulte Llamar a servicios web desde script de cliente.
Permitir el acceso a los servicios web desde script
Para que se puede tener acceso a un servicio web desde script, debe ser un servicio web .asmx cuya clase de servicio web se certifique con el atributo ScriptServiceAttribute. Los métodos individuales que se van a llamar desde el script se deben certificar con el atributo WebMethodAttribute.
En el ejemplo siguiente se muestran estos atributos en código de servicio 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
Para habilitar las llamadas al servicio web desde script, debe registrar el controlador HTTP ScriptHandlerFactory en el archivo Web.config de la aplicación. El controlador procesa las llamadas realizadas desde script a los servicios web .asmx. En el ejemplo siguiente se muestra el elemento Web.config para agregar el controlador.
Nota: |
---|
Esta configuración ya forma parte de la plantilla del archivo Web.config para cualquier sitio web nuevo habilitado para AJAX que cree en Microsoft Visual Studio 2005. |
<system.web>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx"
type="System.Web.Script.Services.ScriptHandlerFactory"
validate="false"/>
</httpHandlers>
<system.web>
Para las llamadas al servicio web que no se emite desde script AJAX de ASP.NET, el controlador ScriptHandlerFactory delega la llamada al controlador predeterminado, que usa el formato SOAP en lugar de JSON. La delegación se realiza automáticamente y no es necesario realizar ninguna acción a menos que desee deshabilitar el uso del protocolo SOAP para los servicios web. En este caso, debe escribir el siguiente valor de configuración en el archivo Web.config.
<system.web>
<webServices> <protocols> <clear/> </protocols> </webServices>
</system.web>
Exponer servicios web a script de cliente en una página web ASP.NET
Para permitir llamar a un servicio web .asmx desde script de cliente en una página web ASP.NET, debe agregar un control ScriptManager a la página. Para hacer referencia al servicio web, agrega un elemento secundario asp:ServiceReference al control ScriptManager y a continuación establece el atributo path de referencia de servidor en la dirección URL del servicio web. El objeto ServiceReference indica a ASP.NET que genere una clase de proxy de JavaScript para llamar al servicio web especificado desde script de cliente.
En el ejemplo siguiente se muestra cómo habilitar un servicio web denominado SimpleWebService.asmx para que se le llame desde script de una página web ASP.NET.
<asp:ScriptManager ID="scriptManager">
<Services>
<asp:ServiceReference
path="~/WebServices/SimpleWebService.asmx" />
</Services>
</asp:ScriptManager>
El objeto ServiceReference sólo puede hacer referencia a un servicio web en el mismo dominio que la página. La ruta de acceso del servicio web puede ser relativa, relativa a la aplicación, relativa al dominio o absoluta. En las rutas de acceso absolutas, debe asegurarse de que la ruta de acceso está en el mismo dominio.
Si se representa una página que contiene este control ScriptManager, la página crea una clase de proxy de JavaScript para el servicio web SimpleWebService.asmx. La clase de proxy incluye métodos que corresponden a los métodos web del servicio SimpleWebService.asmx. La página también contiene clases de proxy de JavaScript que corresponden a los tipos de datos del servidor que se utilizan como parámetros de entrada o valores devueltos de los métodos de servicio web. Esto permite escribir script de cliente que inicialice estos parámetros y pasarlos a la llamada al método.
La propiedad InlineScript del objeto ServiceReference especifica cómo se incluye en la página la clase de proxy de JavaScript. Si InlineScript se establece en false (valor predeterminado), el script de proxy se obtiene realizando una solicitud independiente. Esta opción es preferible cuando varias páginas hacen referencia al mismo servicio y cuando el almacenamiento en caché del explorador está habilitado.
Si InlineScript se establece en true, el script de clase se incluye como un bloque de script insertado en la página. Esto puede mejorar el rendimiento ya que reduce el número de solicitudes de la red. Esto es especialmente cierto si existen muchas referencias al servicio en la página y otras páginas no hacen referencia al mismo servicio. Si InlineScript se establece en true, debe usar una ruta de acceso relativa. Si la ruta de acceso es relativa al dominio, debe hacer referencia a la misma aplicación web.
En los ejemplos siguientes se muestra un servicio web simple al que se llama desde el script que muestra la entrada del usuario y devuelve la hora actual del servidor. En el ejemplo siguiente se muestra la página que realiza las llamadas al servicio a través de script de cliente.
<%@ 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>
En el ejemplo siguiente se muestra el servicio al que se llama a través de script de cliente.
<%@ 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.";
}
}
}
}
Llamar a métodos estáticos en una página web ASP.NET
Puede agregar métodos de página estáticos a una página ASP.NET y certificarlos como métodos web. Después, puede llamar a estos métodos desde script de la página como si formaran parte de un servicio web, pero sin crear un archivo .asmx independiente. Para crear métodos web en una página, importe el espacio de nombres System.Web.Services y agregue un atributo WebMethodAttribute a cada método estático que desee exponer. Los métodos de página se deben definir en la página que realiza la llamada al método de página.
Para llamar a los métodos de página estáticos como métodos web, debe establecer el atributo EnablePageMethods del control ScriptManager en true.
En los ejemplos siguientes se muestra cómo llamar a los métodos de página estáticos desde script de cliente para escribir y leer valores de estado de sesión. En el ejemplo siguiente se muestran métodos de página.
<%@ 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>
En el ejemplo siguiente se muestra el script que se usa para realizar las llamadas a los métodos de página.
// 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();
Para obtener más información acerca del estado de sesión, vea Información general sobre el estado de sesión de ASP.NET.
Vea también
Tareas
Usar el control UpdatePanel con un servicio web
Conceptos
Usar servicios web en ASP.NET para AJAX
Usar servicios web en ASP.NET para AJAX
Exponer servicios de WCF a script de cliente
Llamar a servicios web desde script de cliente
Utilizar la autenticación de formularios con AJAX en ASP.NET