Предоставление доступа к веб-службам в клиентском сценарии
Обновлен: Ноябрь 2007
Функциональные возможности AJAX в ASP.NET обеспечивают вызов веб-служб ASP.NET (файлы с расширением ASMX) из обозревателя с помощью клиентского сценария. Это позволяет расширить возможности пользовательского интерфейса веб-приложения. Вызов серверных методов на странице может выполняться без обратной передачи и без обновления страницы целиком, поскольку между обозревателем и веб-сервером передаются только данные.
В этом подразделе описывается порядок создания веб-службы, доступной для сценариев JavaScript, выполняемых в обозревателе.
В ASP.NET автоматически создаются прокси-классы JavaScript для веб-служб. Эти прокси-классы являются производными от класса Sys.Net.WebServiceProxy. Чтобы вызвать метод веб-службы, следует вызвать соответствующий метод прокси-класса JavaScript. Дополнительные сведения см. в разделе Вызов веб-служб из клиентского сценария.
Предоставление доступа к веб-службе из клиентского сценария
Из сценария можно предоставить доступ к веб-службе, которая представлена файлом с расширением ASMX и класс которой определен с использованием атрибута ScriptServiceAttribute. Отдельные методы, вызываемые из сценария, должны быть дополнены атрибутом WebMethodAttribute.
В следующем примере показан порядок использования этих атрибутов в коде веб-службы.
[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
Чтобы разрешить вызов веб-служб из сценария, следует зарегистрировать обработчик HTTP ScriptHandlerFactory в файле Web.config приложения. Этот обработчик используется для обработки вызовов веб-служб (ASMX) из сценария. В следующем примере показан элемент файла Web.config, определяющий добавление обработчика.
Примечание. |
---|
Эти параметры конфигурации уже определены в шаблоне файла Web.config для любого веб-узла с поддержкой AJAX, создаваемого в 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>
Вызовы веб-служб, выполненные не из сценария ASP.NET AJAX, обработчик ScriptHandlerFactory делегирует используемому по умолчанию обработчику, в котором вместо формата JSON используется SOAP. Делегирование выполняется автоматически. Какие-либо дополнительные действия следует выполнять только в том случае, если требуется запретить использование протокола SOAP в веб-службах. В этом случае в файле Web.config необходимо определить следующие параметры конфигурации.
<system.web>
<webServices> <protocols> <clear/> </protocols> </webServices>
</system.web>
Предоставление доступа к веб-службам из клиентского сценария на веб-странице ASP.NET
Чтобы разрешить вызов веб-служб (ASMX) из клиентского сценария на веб-странице ASP.NET, добавьте на страницу элемент управления ScriptManager. Чтобы определить ссылку на веб-службу, добавьте дочерний элемент asp:ServiceReference к элементу управления ScriptManager. После этого установите URL-адрес веб-службы в качестве значения атрибута ссылки на сервер path. Объект ServiceReference определяет необходимость создания прокси-класса JavaScript для вызова указанной веб-службы в ASP.NET.
В следующем примере показано, как разрешить вызов веб-службы SimpleWebService.asmx на веб-странице ASP.NET.
<asp:ScriptManager runat="server" ID="scriptManager">
<Services>
<asp:ServiceReference
path="~/WebServices/SimpleWebService.asmx" />
</Services>
</asp:ScriptManager>
Объект ServiceReference может ссылаться на веб-службу только в том же домене, в котором находится страница. Путь веб-службы может быть относительным, относительным к приложению, относительным к домену или абсолютным. При использовании абсолютного пути следует убедиться, что он указан в том же домене.
При отображении страницы, содержащей этот элемент управления ScriptManager, для веб-службы SimpleWebService.asmx создается прокси-класс JavaScript. В прокси-классе реализуются методы, соответствующие методам веб-службы SimpleWebService.asmx. Страница также содержит прокси-классы JavaScript, соответствующие типам данных сервера, которые используются в качестве входных параметров или возвращаемых значений методов веб-служб. Это позволяет написать клиентский сценарий, инициализирующий эти параметры, и передать их вызову метода.
Свойство InlineScript объекта ServiceReference определяет порядок включения прокси-класса JavaScript на странице. Если для свойства InlineScript установлено значение false (используется по умолчанию), получение сценария прокси-класса выполняется с помощью отдельного запроса. Этот параметр рекомендуется использовать в том случае, если несколько страниц ссылаются на одну службу и включено кэширование.
Если для свойства InlineScript установлено значение true, сценарий прокси-класса включается на страницу в качестве встроенного блока сценария. Это позволяет повысить производительность за счет сокращения числа сетевых запросов. Это особенно актуально при наличии на странице большого числа ссылок на службы и отсутствии ссылок на эту службу на других страницах. Если для свойства InlineScript установлено значение true, необходимо использовать относительный путь. Путь, задаваемый относительно домена, должен содержать ссылку на то же веб-приложение.
В следующем примере показана простая веб-служба, вызываемая из сценария, в котором отображаются вводимые пользователем данные и возвращается текущее серверное время. В следующем примере показана страница, на которой выполняется вызов службы с помощью клиентского сценария.
<%@ 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" runat="server">
<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" runat="server">
<asp:ScriptManager runat="server" 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" runat="server">
<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" runat="server">
<asp:ScriptManager runat="server" 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 статические методы и определить их как веб-методы. Затем эти методы можно вызывать из сценариев страницы в качестве элементов веб-службы, но без создания отдельного файла с расширением ASMX. Чтобы создать веб-методы на странице, выполните импорт пространства имен System.Web.Services и добавьте атрибут WebMethodAttribute к каждому статическому методу, доступ к которому необходимо предоставить. Методы страницы должны быть определены на странице, на которой выполняется их вызов.
Для вызова статических методов страницы в качестве веб-методов следует установить для атрибута EnablePageMethods элемента управления ScriptManager значение 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 runat="server">
<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" runat="server">
<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" runat="server">
<asp:ScriptManager ID="ScriptManager1"
runat="server" 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 runat="server">
[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" runat="server">
<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" runat="server">
<asp:ScriptManager ID="ScriptManager1"
runat="server" 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.
См. также
Задачи
Использование элемента управления UpdatePanel c веб-службой
Основные понятия
Использование веб-служб в технологии AJAX ASP.NET
Использование веб-служб в технологии AJAX ASP.NET
Предоставление доступа к службам WCF в клиентском сценарии
Вызов веб-служб из клиентского сценария
Использование проверки подлинности с помощью форм в ASP.NET AJAX