Поделиться через


Вызов веб-служб из клиентского сценария

Обновлен: Ноябрь 2007

В этом разделе описывается порядок использования функций AJAX ASP.NET для вызова веб-служб из языка ECMAScript (JavaScript). Чтобы реализовать в приложении вызов веб-служб ASP.NET с использованием клиентского сценария, на уровне связи веб-службы сервера автоматически создаются прокси-классы JavaScript. Прокси-класс создается для каждой веб-службы, на которую ссылается элемент ServiceReference элемента управления ScriptManager на странице.

В качестве веб-службы может выступать веб-служба ASP.NET Web (ASMX-службы) или служба Windows Communication Foundation (WCF) (SVC-службы). Если веб-службы ASP.NET (ASMX) уже созданы, можно изменить их, чтобы разрешить их вызов из сценария, содержащегося на веб-странице с поддержкой AJAX. Дополнительные сведения см. в разделе Предоставление доступа к веб-службам в клиентском сценарии. Если службы WCF уже созданы, можно добавить конечные точки, чтобы разрешить доступ к этим службам из сценария, содержащегося на веб-странице с поддержкой AJAX. Дополнительные сведения см. в разделе Предоставление доступа к службам WCF в клиентском сценарии.

Чтобы вызвать метод веб-службы, следует вызвать соответствующий метод созданного прокси-класса JavaScript. Прокси-класс, в свою очередь, обеспечивает взаимодействие с веб-службой.

Вызов методов веб-служб

Вызов метода веб-службы из сценария осуществляется асинхронным способом. Чтобы получить возвращаемое значение или определить факт возврата запроса, следует определить функцию обратного вызова при успешном выполнении запроса. Функция обратного вызова вызывается при успешном выполнении запроса и содержит значение (если есть), возвращаемое в результате вызова метода веб-службы. Также можно определить функцию обратного вызова при неудачном завершении запроса, используемую для обработки ошибок. Кроме того, можно передать в функции обратного вызова сведения о контексте пользователя.

В следующем примере показан порядок выполнения следующих типов вызова веб-служб.

  • вызов веб-службы, которая не возвращает значение;

  • вызов веб-службы, которая возвращает значение;

  • вызов метода веб-службы, который принимает параметры;

  • вызов метода веб-службы с использованием команды HTTP GET;

  • вызов метода веб-службы, который возвращает объект XmlDocument.

В первой части примера показана веб-страница, на которой выполняется вызов веб-службы с использованием клиентского сценария.

<%@ 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>Calling Web Methods</title>

    </head>

    <body>
        <form id="Form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManagerId">
                <Scripts>
                    <asp:ScriptReference Path="CallWebServiceMethods.js" />
                </Scripts>
                <Services>
                    <asp:ServiceReference  Path="WebService.asmx" />
                </Services>

            </asp:ScriptManager>

            <div>
                <h2>Calling Web Methods</h2>






               <table>
                    <tr align="left">
                        <td>Method that does not return a value:</td>
                        <td>
                            <!-- Getting no retun value from 
                            the Web service. --> 
                            <button id="Button1"  
                                onclick="GetNoReturn()">No Return</button>
                        </td>
                    </tr>
                    <tr align="left">
                        <td>Method that returns a value:</td>
                        <td>
                            <!-- Getting a retun value from 
                            the Web service. --> 
                            <button id="Button2" 
                                onclick="GetTime(); return false;">Server Time</button>
                        </td>
                   </tr>
                   <tr align="left">
                        <td>Method that takes parameters:</td>
                        <td>
                            <!-- Passing simple parameter types to 
                            the Web service. --> 
                            <button id="Button3" 
                                onclick="Add(20, 30); return false;">Add</button>
                        </td>
                    </tr>
                    <tr align="left">
                        <td>Method that returns XML data:</td>
                        <td>   
                             <!-- Get Xml. --> 
                            <button id="Button4" 
                                onclick="GetXmlDocument(); return false;">Get Xml</button>
                        </td>
                    </tr>
                    <tr align="left">
                        <td>Method that uses GET:</td>
                        <td>   
                             <!-- Making a GET Web request. --> 
                            <button id="Button5" 
                                onclick="MakeGetRequest(); return false;">Make GET Request</button>
                        </td>
                    </tr>
                </table>

            </div>
        </form>

        <hr/>

        <div>
            <span id="ResultId"></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>Calling Web Methods</title>

    </head>

    <body>
        <form id="Form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManagerId">
                <Scripts>
                    <asp:ScriptReference Path="CallWebServiceMethods.js" />
                </Scripts>
                <Services>
                    <asp:ServiceReference  Path="WebService.asmx" />
                </Services>

            </asp:ScriptManager>

            <div>
                <h2>Calling Web Methods</h2>






               <table>
                    <tr align="left">
                        <td>Method that does not return a value:</td>
                        <td>
                            <!-- Getting no retun value from 
                            the Web service. --> 
                            <button id="Button1"  
                                onclick="GetNoReturn()">No Return</button>
                        </td>
                    </tr>
                    <tr align="left">
                        <td>Method that returns a value:</td>
                        <td>
                            <!-- Getting a retun value from 
                            the Web service. --> 
                            <button id="Button2" 
                                onclick="GetTime(); return false;">Server Time</button>
                        </td>
                   </tr>
                   <tr align="left">
                        <td>Method that takes parameters:</td>
                        <td>
                            <!-- Passing simple parameter types to 
                            the Web service. --> 
                            <button id="Button3" 
                                onclick="Add(20, 30); return false;">Add</button>
                        </td>
                    </tr>
                    <tr align="left">
                        <td>Method that returns XML data:</td>
                        <td>   
                             <!-- Get Xml. --> 
                            <button id="Button4" 
                                onclick="GetXmlDocument(); return false;">Get Xml</button>
                        </td>
                    </tr>
                    <tr align="left">
                        <td>Method that uses GET:</td>
                        <td>   
                             <!-- Making a GET Web request. --> 
                            <button id="Button5" 
                                onclick="MakeGetRequest(); return false;">Make GET Request</button>
                        </td>
                    </tr>
                </table>

            </div>
        </form>

        <hr/>

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

    </body>

</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

// This function calls the Web service method without 
// passing the callback function. 
function GetNoReturn()
{
    Samples.AspNet.WebService.GetServerTime();
    alert("This method does not return a value.");

}


// This function calls the Web service method and 
// passes the event callback function.  
function GetTime()
{
    Samples.AspNet.WebService.GetServerTime(
    SucceededCallback);

}


// This function calls the Web service method 
// passing simple type parameters and the 
// callback function  
function Add(a,  b)
{
    Samples.AspNet.WebService.Add(a, b, 
    SucceededCallback);
}

// This function calls the Web service method 
// that returns an XmlDocument type.  
function GetXmlDocument() 
{
    Samples.AspNet.WebService.GetXmlDocument(
        SucceededCallbackWithContext, FailedCallback,
        "XmlDocument")
}

// This function calls a Web service method that uses
// GET to make the Web request.
function MakeGetRequest() 
{

    Samples.AspNet.WebService.EchoStringAndDate(
        new Date("1/1/2007"), " Happy",
        SucceededCallback, 
        FailedCallback, "HappyNewYear");

}

// This is the callback function invoked if the Web service
// succeeded.
// It accepts the result object, the user context, and the 
// calling method name as parameters.
function SucceededCallbackWithContext(result, userContext, methodName)
{
    var output;

    // Page element to display feedback.
    var RsltElem = document.getElementById("ResultId");

    var readResult;
    if (userContext == "XmlDocument")
    {
    
        if (document.all) 
            readResult = 
                result.documentElement.firstChild.text;
        else
            // Firefox
           readResult =
                result.documentElement.firstChild.textContent;
        
         RsltElem.innerHTML = "XmlDocument content: " + readResult;
    }

}

// This is the callback function invoked if the Web service
// succeeded.
// It accepts the result object as a parameter.
function SucceededCallback(result, eventArgs)
{
    // Page element to display feedback.
    var RsltElem = document.getElementById("ResultId");
    RsltElem.innerHTML = result;
}


// This is the callback function invoked if the Web service
// failed.
// It accepts the error object as a parameter.
function FailedCallback(error)
{
    // Display the error.    
    var RsltElem = 
        document.getElementById("ResultId");
    RsltElem.innerHTML = 
    "Service Error: " + error.get_message();
}

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

В следующей части примера показана вызываемая на странице веб-служба.

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

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 WebService
        Inherits System.Web.Services.WebService

        Private _xmlString As String = _
        "<?xml version=""1.0"" encoding=""utf-8"" ?>" + _
        "  <message>" + _
        "    <content>" + _
        "      Welcome to the asynchronous communication layer world!" + _
        "    </content>" + _
        " </message>"

        ' This method returns an XmlDocument type.
        <WebMethod()> _
        <ScriptMethod(ResponseFormat:=ResponseFormat.Xml)> _
        Public Function GetXmlDocument() As XmlDocument
            Dim xmlDoc As New XmlDocument()
            xmlDoc.LoadXml(_xmlString)
            Return xmlDoc

        End Function 'GetXmlDocument


        ' This method uses GET instead of POST.
        ' Its input parameters are sent by the 
        ' client in the URL query string.
        <WebMethod()> _
        <ScriptMethod(UseHttpGet:=True)> _
        Public Function EchoStringAndDate(ByVal dt As DateTime, _
        ByVal s As String) As String
            Return s + ":" + dt.ToString()
        End Function 'EchoStringAndDate

        <WebMethod()> _
        Public Function GetServerTime() As String

            Dim serverTime As String = _
            String.Format("The current time is {0}.", DateTime.Now)

            Return serverTime

        End Function 'GetServerTime


        <WebMethod()> _
        Public Function Add(ByVal a As Integer, _
        ByVal b As Integer) As String

            Dim addition As Integer = a + b
            Dim result As String = _
            String.Format("The addition result is {0}.", addition.ToString())

            Return result

        End Function 'Add

        <WebMethod()> _
        <ScriptMethod(ResponseFormat:=ResponseFormat.Xml, _
            XmlSerializeString:=True)> _
        Public Function GetString() As String
            Return "Hello World"
        End Function

    End Class 'WebService 

End Namespace

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

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 WebService : System.Web.Services.WebService
    {

        private string _xmlString =
            @"<?xml version=""1.0"" encoding=""utf-8"" ?>
                <message>
                    <content>
                        Welcome to the asynchronous communication layer world!
                    </content>
                </message>";

        // This method returns an XmlDocument type.
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
        public XmlDocument GetXmlDocument()
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(_xmlString);
            return xmlDoc;
        }

        // This method uses GET instead of POST.
        // For this reason its input parameters
        // are sent by the client in the
        // URL query string.
        [WebMethod]
        [ScriptMethod(UseHttpGet = true)]
        public string EchoStringAndDate(DateTime dt, string s)
        {
            return s + ":" + dt.ToString();
        }

        [WebMethod]
        public string GetServerTime()
        {

            string serverTime =
                String.Format("The current time is {0}.", DateTime.Now);

            return serverTime;

        }

        [WebMethod]
        public string Add(int a, int b)
        {

            int addition = a + b;
            string result = 
                String.Format("The addition result is {0}.", 
                    addition.ToString());

            return result;

        }

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Xml, 
            XmlSerializeString = true)]
        public string GetString()
        {
            return "Hello World";           
        }

    }

}

Определение функций обратного вызова в качестве используемых по умолчанию свойств

В предыдущих примерах вызов методов веб-службы выполняется с использованием прокси-класса. Сведения о функциях обратного вызова при успешном и неудачном выполнении запроса, а также о контексте пользователя передаются с помощью дополнительных параметров вызова.

Кроме того, можно задать функции обратного вызова при успешном и неудачном выполнении запроса, а также контекст пользователя в качестве используемых по умолчанию свойств класса. В этом случае можно вызывать из сценария методы прокси-класса, соответствующие методам веб-службы, не передавая эти значения в качестве параметров вызова. Это позволяет упростить синтаксис вызова методов веб-службы.

В следующем примере показан порядок установки используемых по умолчанию свойств прокси-класса веб-службы и последующего вызова метода веб-службы:

MyNameSpace.MyService.set_defaultSucceededCallback(SucceededCallback);
MyNameSpace.MyService.set_defaultFailedCallback(FailedCallback);
MyNameSpace.MyService.set_defaultUserContext("my context");
MyNameSpace.MyService.myServiceMethod(param1, param2);

Определение функций обратного вызова в качестве свойств экземпляра прокси-класса

При необходимости можно создать экземпляры автоматически созданного прокси-класса. В этом случае можно задать функции обратного вызова при успешном и неудачном выполнении запроса, а также контекст пользователя в качестве используемых по умолчанию свойств каждого экземпляра. Как и при вызове созданного прокси-класса, после этого можно использовать экземпляры прокси-класса для вызова методов веб-службы, не передавая эти значения в качестве параметров вызова.

Экземпляры прокси-класса обычно создаются в тех случаях, когда необходимо выполнить несколько вызовов методов веб-службы с использованием различных значений по умолчанию для каждого экземпляра. Например, можно определить разные функции обратного вызова для каждого экземпляра. Используя разные функции обратного вызова, возвращаемые данные можно обрабатывать различными способами, в зависимости от их характера и потребностей приложения.

В следующем примере показан порядок создания экземпляра прокси-класса, установки его свойств по умолчанию, а также вызова связанного метода веб-службы:

var myServiceProxy = new MyNameSpace.MyService();
myServiceProxy.set_defaultSucceededCallback(SuccededCallback);
myServiceProxy.set_defaultFailedCallback(FailedCallback);
MyNameSpce.MyService.set_defaultUserContext("my context");
myServiceProxy.myServiceMethod(param1, param2); 

Дополнительные сведения см. в разделе Созданные прокси-классы.

Обработка ошибок при вызове методов веб-службы

Для перехвата ошибок следует определить функцию обратного вызова при неудачном завершении запроса, принимающую один параметр. В этом параметре содержится объект ошибки, передаваемый веб-службой.

В следующем примере показан порядок определения функции обратного вызова при неудачном завершении запроса, которая вызывается при возникновении ошибки в процессе вызова метода веб-службы. В первой части примера показана веб-страница, на которой выполняется вызов веб-службы с использованием клиентского сценария.

<%@ Page Language="VB" %>

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

<script runat="server">

</script>

<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>Handling Web Service Error</title>



</head>
  <body>
        <form id="Form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManagerId">

                <Scripts>
                    <asp:ScriptReference Path="WebServiceMethodError.js" />
                </Scripts>
                <Services>
                    <asp:ServiceReference  Path="WebService.asmx" />
                </Services>

            </asp:ScriptManager>
            <div>
                <h2>Handling Web Service Error</h2>


                <table>
                    <tr align="left">
                        <td>Method with error:</td>
                        <td>
                           <!-- Cause divide by zero failure. --> 
                            <button id="Button1" 
                                onclick="Div(10, 0); return false;">Div Error</button>
                        </td>
                    </tr>
                </table>

            </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>Handling Web Service Error</title>


    </head>

    <body>
        <form id="Form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManagerId">

                <Scripts>
                    <asp:ScriptReference Path="WebServiceMethodError.js" />
                </Scripts>
                <Services>
                    <asp:ServiceReference  Path="WebService.asmx" />
                </Services>

            </asp:ScriptManager>
            <div>
                <h2>Handling Web Service Error</h2>


                <table>
                    <tr align="left">
                        <td>Method with error:</td>
                        <td>
                           <!-- Cause divide by zero failure. --> 
                            <button id="Button1" 
                                onclick="Div(10, 0); return false;">Div Error</button>
                        </td>
                    </tr>
                </table>

            </div>
        </form>

        <hr/>

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

    </body>

</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

// This function can cause a divide by zero error.  
function Div(a, b)
{
    Samples.AspNet.WebService.Div(a, b, 
        SucceededCallback, FailedCallback);
}

// This is the failed callback function.
function FailedCallback(error)
{
    var stackTrace = error.get_stackTrace();
    var message = error.get_message();
    var statusCode = error.get_statusCode();
    var exceptionType = error.get_exceptionType();
    var timedout = error.get_timedOut();

    // Display the error.    
    var RsltElem = 
        document.getElementById("Results");
    RsltElem.innerHTML = 
        "Stack Trace: " +  stackTrace + "<br/>" +
        "Service Error: " + message + "<br/>" +
        "Status Code: " + statusCode + "<br/>" +
        "Exception Type: " + exceptionType + "<br/>" +
        "Timedout: " + timedout;
}

// This is the succeeded callback function.
function SucceededCallback(result)
{
    // Display the result.
    var RsltElem = document.getElementById("Results");
    RsltElem.innerHTML = result;
}

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

В следующей части примера показана вызываемая на странице веб-служба.

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

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 WebService
        Inherits System.Web.Services.WebService

        <WebMethod()> _
        Public Function Div(ByVal a As Integer, _
        ByVal b As Integer) As String

            Dim division As Integer = a / b
            Dim result As String = _
            String.Format("The division result is {0}.", division.ToString())

            Return result

        End Function 'Div 

    End Class 'WebService 

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

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 WebService : System.Web.Services.WebService
    {

        [WebMethod]
        public string Div(int a, int b)
        {

            int division = a / b;
            string result =
                String.Format("The division result is {0}.",
                    division.ToString());

            return result;


        }


    }


}

Вызов одной функции обратного вызова из нескольких методов веб-службы

Можно определить одну функцию обратного вызова при успешном выполнении запроса, которая вызывается из нескольких методов веб-службы. Чтобы однозначно определить вызывающий объект, в функцию передается контекст пользователя или выполняется проверка имени вызывающего метода. Контекст пользователя и имя вызывающего метода одновременно доступны в функции обратного вызова.

В следующем примере показан порядок вызова одной функции обратного вызова из нескольких запросов веб-службы. В первой части примера показана веб-страница, на которой выполняется вызов веб-службы с использованием клиентского сценария.

<%@ 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>Passing user context or method name</title>

    </head>

    <body>
        <form id="Form1" runat="server">

             <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="WebService_VB.asmx" />
                </Services>

                <Scripts>
                    <asp:ScriptReference Path="WebServiceMultipleCallers.js" />
                </Scripts>

            </asp:ScriptManager>

            <div>
                <h2>Passing User Context or Method Name</h2>

                <table>
                    <tr align="left">
                        <td>Passing user context:</td>
                        <td>
                            <button id="Button1" 
                                onclick="AddWithContext(10, 20, 'user context information'); return false;">User Context</button>
                        </td>
                    </tr>
                    <tr align="left">
                      <td>Passing method:</td>
                      <td>   
                        <button id="Button7" 
                            onclick="AddWithMethod(10, 30); return false;">Method Name</button>
                      </td>
                    </tr>
                </table>

            </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>Passing user context or method name</title>


    </head>

    <body>
        <form id="Form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="WebService.asmx" />
                </Services>

                <Scripts>
                    <asp:ScriptReference Path="WebServiceMultipleCallers.js" />
                </Scripts>

            </asp:ScriptManager>
            <div>
                <h2>Passing User Context or Method Name</h2>

                <table>
                    <tr align="left">
                        <td>Passing user context:</td>
                        <td>
                            <button id="Button1" 
                                onclick="AddWithContext(10, 20, 'user context information'); return false;">User Context</button>
                        </td>
                    </tr>
                    <tr align="left">
                      <td>Passing method:</td>
                      <td>   
                        <button id="Button7" 
                            onclick="AddWithMethod(10, 30); return false;">Method Name</button>
                      </td>
                    </tr>
                </table>

            </div>
        </form>

        <hr/>

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

    </body>

</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

// This function calls a Web service method 
// passing simple type parameters and the user context.  
function AddWithContext(a,  b, userContext)
{
    Samples.AspNet.WebService.Add(a, b, 
    SucceededCallbackWithContext, FailedCallback, userContext, null);
}


// This function calls the Web service method 
// passing the method name.  
function AddWithMethod(a,  b)
{
    Samples.AspNet.WebService.Add(a, b, 
    SucceededCallbackWithContext, FailedCallback);
}

// This is the callback function called if the
// Web service succeeded. It accepts the result
// object, the user context, and the method name as
// parameters.
function SucceededCallbackWithContext(result, userContext, methodName)
{
    // It holds feedback message.
    var output = "";
    
    // Page element to display the feedback message.    
    var RsltElem = 
        document.getElementById("Results");

    if (userContext)
    {
        output += "The user context is : " + userContext + "<br/>";
        RsltElem.innerHTML =  output;
        return;
    }

    if (methodName) 
      output += "The method name is : " + methodName + "<br/>";
      
    RsltElem.innerHTML =  output;
    
}

// This is the callback function called if the
// Web service failed. It accepts the error object
// as a parameter.
function FailedCallback(error)
{
    // Display the error.    
    var RsltElem = 
        document.getElementById("Results");
    RsltElem.innerHTML = 
        "Service Error: " + error.get_message();
}

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

В следующей части примера показана вызываемая на странице веб-служба.

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

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 WebService
        Inherits System.Web.Services.WebService

        <WebMethod()> _
        Public Function Add(ByVal a As Integer, _
        ByVal b As Integer) As String

            Dim addition As Integer = a + b
            Dim result As String = _
            String.Format("The addition result is {0}.", addition.ToString())

            Return result

        End Function 'Add

    End Class 'WebService 

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

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 WebService : System.Web.Services.WebService
    {

        [WebMethod]
        public string Add(int a, int b)
        {

            int addition = a + b;
            string result =
                String.Format("The addition result is {0}.",
                    addition.ToString());

            return result;

        }


    }


}

Передача и возврат сложных типов

Если метод веб-службы возвращает сложный тип, функция обратного вызова при успешном выполнении запроса принимает возвращаемое значение в форме объекта JavaScript, соответствующего типу сервера.

В следующем примере показан метод веб-службы, возвращающий сложный тип. В первой части примера показана веб-страница, на которой выполняется вызов веб-службы с использованием клиентского сценария.

<%@ Page Language="VB" %>

<%@ Import Namespace="System.Web.Script.Serialization" %>

<!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">

        <title>Receiving Complex Type</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>Receiving Complex Type</h2>

        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference  Path="HandleColor.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="HandleColor.js" />
                </Scripts>
            </asp:ScriptManager>  

            <table style="font-size:12px">
                <tr>
                    <td>Web Service Default Color:</td>
                    <td>
                     <button id="Button1" 
                        onclick="GetDefaultColor(); return false;">Get Default Color</button>
                    </td>
                </tr>
            </table> 

           <hr />

            <!-- Display current color object. -->
            <p>
                <span style="background-color:Yellow">Color:</span>
                <span id="ResultId"></span>
            </p>


        </form>

    </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">

        <title>Receiving Complex Type</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>Receiving Complex Type</h2>

        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference  Path="HandleColor.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="HandleColor.js" />
                </Scripts>
            </asp:ScriptManager>  

            <table style="font-size:12px">
                <tr>
                    <td>Web Service Default Color:</td>
                    <td>
                     <button id="Button1" 
                        onclick="GetDefaultColor(); return false;">Get Default Color</button>
                    </td>
                </tr>
            </table> 

           <hr />

            <!-- Display current color object. -->
            <p>
                <span style="background-color:Yellow">Color:</span>
                <span id="ResultId"></span>
            </p>


        </form>

    </body>

</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

// It gets the default color
// from the Web service.
function GetDefaultColor()  
{
    // Call the Web service method to get 
    // the default color.
    Samples.AspNet.HandleColor.GetDefaultColor(
        SucceededCallback);  

}

// This is the callback function that 
// processes the complex type returned  
// by the Web service.
function SucceededCallback(result)
{

    // Read the values returned by the
    // Web service.
    var message = result.message;
    var rgb = result.rgb;
    var timeStamp = result.timeStamp;

    // Transform the rgb array into a string.
    var serverColor = rgb[0]+ rgb[1] + rgb[2];

    // Display the result.
    var displayResult = 
        document.getElementById("ResultId");
    displayResult.style.color = "yellow";
    displayResult.style.fontWeight = "bold";
    if (document.all) 
        displayResult.innerText = message + " " + timeStamp;
    else
       // Firefox
       displayResult.textContent = message + " " + timeStamp;
    displayResult.style.backgroundColor = "#" + serverColor;

}

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

В следующей части примера показана вызываемая на странице веб-служба.

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

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Web.Script.Services
Imports System.Web.Script.Serialization

Namespace Samples.AspNet
    ' Define the color object to
    ' exchange with the client.
    Public Class ColorObject
        Public message As String = "The default color is Blue."
        Public rgb() As String = {"00", "00", "FF"}
        Public timeStamp As String
    End Class 'ColorObject 

    <WebService([Namespace]:="http://tempuri.org/")> _
    <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
    <GenerateScriptType(GetType(ColorObject))> _
    <ScriptService()> _
    Public Class HandleColor
        Inherits System.Web.Services.WebService


        <WebMethod()> _
        Public Function GetDefaultColor() As ColorObject
            ' Instantiate the default color object.
            Dim co As New ColorObject()
            ' Set time stamp.
            co.timeStamp = DateTime.Now.ToString()

            Return co

        End Function 'GetDefaultColor


        <WebMethod()> _
        Public Function ChangeDefaultColor( _
        ByVal color As ColorObject) As ColorObject
            ' Instantiate the default color object.
            Dim co As New ColorObject()
            ' Assign the passed values.
            co.message = color.message
            co.rgb = color.rgb
            ' Set time stamp.
            co.timeStamp = DateTime.Now.ToString()

            Return co

        End Function 'ChangeDefaultColor 

    End Class 'HandleColor

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

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

namespace Samples.AspNet
{
    // Define the color object to
    // exchange with the client.
    public class ColorObject
    {
        public string message = 
             "The default color is Blue.";
        public string[] rgb =
            new string[] { "00", "00", "FF" }; 
        public string timeStamp;

    }

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


        [WebMethod]
        public ColorObject GetDefaultColor()
        {
            // Instantiate the default color object.
            ColorObject co = new ColorObject();
            // Set time stamp.
            co.timeStamp = DateTime.Now.ToString();

            return co;         
        }


        [WebMethod]
        public ColorObject ChangeDefaultColor(ColorObject color)
        {
            // Instantiate the default color object.
            ColorObject co = new ColorObject();
            // Assign the passed values.
            co.message = color.message;
            co.rgb = color.rgb;
            // Set time stamp.
            co.timeStamp = DateTime.Now.ToString();

            return co;

        }


    }

}

В следующем примере показан порядок вызова методов веб-службы, которые содержат параметры соответствующих сложных типов. Соответствующие типам прокси-классы создаются автоматически. Это позволяет создавать из клиентского сценария экземпляры типа, которые передаются в качестве параметров вызова метода.

В первой части примера показана веб-страница, на которой выполняется вызов веб-службы с использованием клиентского сценария.

<%@ Page Language="VB" %>

<%@ Import Namespace="System.Web.Script.Serialization" %>

<!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">

        <title>Exchanging Complex Types</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>Exchanging Complex Types</h2>

        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="HandleColor.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="HandleColor.js" />
                </Scripts>
            </asp:ScriptManager>  

        </form>


        <center>
            <table style="font-size:12px;" >
                <tr align="center">
                    <td class="text">Change Color:</td>
                    <td>
                        <select id="ColorSelectID"   
                            onchange="OnChangeDefaultColor(this);" runat="server">
                        </select>
                    </td>
                </tr>
            </table> 
        </center>

        <hr />

        <!-- Display current color object. -->
        <span style="background-color:Yellow">Color:</span>
        <span id="ResultId"></span>

    </body>

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

<%@ Import Namespace="System.Web.Script.Serialization" %>

<!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">

        <title>Exchanging Complex Types</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>Exchanging Complex Types</h2>

        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="HandleColor.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="HandleColor.js" />
                </Scripts>
            </asp:ScriptManager>  

        </form>


        <center>
            <table style="font-size:12px;" >
                <tr align="center">
                    <td class="text">Change Color:</td>
                    <td>
                        <select id="ColorSelectID"   
                            onchange="OnChangeDefaultColor(this);" runat="server">
                        </select>
                    </td>
                </tr>
            </table> 
        </center>

        <hr />

        <!-- Display current color object. -->
        <span style="background-color:Yellow">Color:</span>
        <span id="ResultId"></span>

    </body>

</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

 // The Web service default color.
 var defaultRgb;

 // The page feedback display element.
 var displayResult;

// Gets the selection list colors and 
// the default color from the Web service.
function GetServerColors()  
{
  // Gets the default color.
    Samples.AspNet.HandleColor.GetDefaultColor(
        SucceededCallback, FailedCallback);  

    // Get selection list colors.
    Samples.AspNet.HandleColor.GetColorList(
        SucceededCallback, FailedCallback);


}

// This function passes the color selected
// by the user (client) to the Web service.
function OnChangeDefaultColor(comboObject)  
{
    // Create an instance 
    // of the server color object.
    var color = 
        new Samples.AspNet.ColorObject();

    // Get the user's selected color.
    var selectionIndex = 
        comboObject.selectedIndex;
    var selectedColor = 
        comboObject.options[selectionIndex].text;    

    // Get the related RGB color value.
    var selectionValue = 
        comboObject.value;
    // Transform it into an array.
    var colorArray = selectionValue.split(",");

    // Assign the new values to 
    // the server color object.
    color.message = "The new default color is " + selectedColor + ".";
    color.rgb = colorArray;

    // Call the Web service method to change the color.
    Samples.AspNet.HandleColor.ChangeDefaultColor(
        color, SucceededCallback, FailedCallback);  
}

// This is the callback function that processes 
// the complex type returned by the Web service.
function SucceededCallback(result, userContext, methodName)
{ 
    switch(methodName)
    {
        case ("GetColorList"):
        {
            // Get the select object.
            var selectObject = document.getElementById("ColorSelectID");
            var i = 0;

            // Iterate through the dictionary to populate 
            // the selection list.
            for(var item in result)
            {        
                var option = new Option(result[item], item);
                selectObject.options[i]=option;

                // Set the default selection.        
                if (item == defaultRgb)
                    selectObject.options[i].selected = true;
               i++;
            }
            break;
        }
        default:
        {
            // Get the server default color and its current time.
            // Read the values returned by the
            // Web service.
            var message = result.message;
            defaultRgb = result.rgb;

            var timeStamp = result.timeStamp;

            // Transform the rgb array into a string.
            var serverColor = defaultRgb[0]+ defaultRgb[1] + defaultRgb[2];

            // Display the result.
            displayResult.style.color = "yellow";
            displayResult.style.fontWeight = "bold";
            if (document.all) 
                displayResult.innerText = message + " " + timeStamp;
            else
               // Firefox
               displayResult.textContent = message + " " + timeStamp;

            displayResult.style.backgroundColor = "#" + serverColor;
            break;
        }
    }            
}

// Callback function invoked on failure 
// of the Web service methods.
function FailedCallback(error, userContext, methodName) 
{
    if(error !== null) 
    {
        displayResult.innerHTML = "An error occurred: " + 
            error.get_message();
    }
}

// Gets the Web service selection list colors 
// and the default color.
function pageLoad() 
{
    // Get page feedback display element.
    displayResult = 
        document.getElementById("ResultId");
    // Get the server's selection list colors and 
    // the default color.
    GetServerColors();
}


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

В следующей части примера показана вызываемая на странице веб-служба.

<%@ WebService Language="C#" Class="Samples.AspNet.HandleColor" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
using System.Web.Script.Serialization;
using System.Collections.Generic;

namespace Samples.AspNet
{
    // Define the color object to
    // exchange with the client.
    public class ColorObject
    {
        public string message;
        public string[] rgb; 
        public string timeStamp;

        public ColorObject()
        {
            this.message = "The default color is Red.";
            this.rgb = new string[] { "FF", "00", "00" };
            this.timeStamp = DateTime.Now.ToString();
        }
    }

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


        [WebMethod]
        public ColorObject GetDefaultColor()
        {
            // Instantiate the default color object.
            ColorObject co = new ColorObject();
            return co;         
        }


        [WebMethod]
        public ColorObject ChangeDefaultColor(ColorObject color)
        {
            // Instantiate the default color object.
            ColorObject co = new ColorObject();
            // Assign the passed values.
            co.message = color.message;
            co.rgb = color.rgb;
            // Set time stamp.
            co.timeStamp = DateTime.Now.ToString();
            return co;
        }

        [WebMethod]

        public Dictionary<String,String> GetColorList()
        {
            //Instatiate the dictionary object.
            Dictionary<String, String> result = new Dictionary<string, string>();

            //Add the color items.
            result.Add("00,00,FF", "Blue");
            result.Add("FF,00,00", "Red");
            result.Add("00,FF,00", "Green");
            result.Add("00,00,00", "Black");

            return result;
        }          
    }

}

Передача параметров, типизированных как универсальные параметры или массивы

В методах веб-службы могут поддерживаться параметры или возвращаемые значения, типизированные как универсальные параметры или массивы списков типа T. В этом случае средствами ASP.NET автоматически создаются используемые в клиентском сценарии прокси-классы для типа T.

Обратите внимание, что в ASP.NET не поддерживается автоматическое создание прокси-классов для универсальных типов, принимающих несколько аргументов типа, например Dictionary<string, <T>>. Для автоматического создания прокси-класса для типа T в ASP.NET необходимо определить класс веб-службы, в котором используется этот тип, с помощью атрибута GenerateScriptTypeAttribute для типа T.

В следующем примере показан порядок вызова метода веб-службы, параметры которого типизированы как универсальные параметры или массивы, из клиентского сценария. В первой части примера показана веб-страница, на которой выполняется вызов веб-службы с использованием клиентского сценария.

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

        <title>Using Generics Proxy Types</title>
        <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }
           .text { font: 10pt Trebuchet MS; text-align: center }
        </style>    
    </head>

    <body>

        <h2>Using Generics Proxy Types</h2>


        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="WebService.asmx" />
                    <asp:ServiceReference Path="WebService2.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="generics.js" />
                </Scripts>
            </asp:ScriptManager>  

        </form>


        <center>
            <table style="font-size:12px;" >

                <tr align="left">
                    <td class="text">Generic List:</td>
                    <td>
                        <button id="Button1"  
                            onclick="GenericList()">Get List</button>
                    </td>
                </tr>

               <tr align="left">
                    <td class="text">Generic Dictionary:</td>
                    <td>
                     <button id="Button2"  
                        onclick="GenericDictionary()">Get Dictionary</button>
                    </td>
                </tr>

                 <tr align="left">
                    <td class="text">Generic Custom Type Dictionary:</td>
                    <td>
                     <button id="Button3"  
                        onclick="GenericCustomTypeDictionary()">Get Dictionary</button>
                    </td>
                </tr>


                <tr align="left">
                    <td class="text">Generic Dictionary:</td>
                    <td>
                     <button id="Button5"  
                        onclick="PassGenericDictionary()">Pass Dictionary</button>
                    </td>
                </tr>


                <tr align="left">
                    <td class="text">Array:</td>
                    <td>
                     <button id="Button4"  
                        onclick="ArrayType()">Get Array</button>
                    </td>
                </tr>

            </table> 
        </center>

        <hr />

        <!-- Display current color object. -->
        <span id="ResultId"></span>

    </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">

        <title>Using Generics Proxy Types</title>
        <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }
           .text { font: 10pt Trebuchet MS; text-align: center }
        </style>    
    </head>

    <body>

        <h2>Using Generics Proxy Types</h2>


        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="WebService.asmx" />
                    <asp:ServiceReference Path="WebService2.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="generics.js" />
                </Scripts>
            </asp:ScriptManager>  

        </form>


        <center>
            <table style="font-size:12px;" >

                <tr align="left">
                    <td class="text">Generic List:</td>
                    <td>
                        <button id="Button1"  
                            onclick="GenericList()">Get List</button>
                    </td>
                </tr>

               <tr align="left">
                    <td class="text">Generic Dictionary:</td>
                    <td>
                     <button id="Button2"  
                        onclick="GenericDictionary()">Get Dictionary</button>
                    </td>
                </tr>

                 <tr align="left">
                    <td class="text">Generic Custom Type Dictionary:</td>
                    <td>
                     <button id="Button3"  
                        onclick="GenericCustomTypeDictionary()">Get Dictionary</button>
                    </td>
                </tr>


                <tr align="left">
                    <td class="text">Generic Dictionary:</td>
                    <td>
                     <button id="Button5"  
                        onclick="PassGenericDictionary()">Pass Dictionary</button>
                    </td>
                </tr>

                 <tr align="left">
                    <td class="text">Array:</td>
                    <td>
                     <button id="Button4"  
                        onclick="ArrayType()">Get Array</button>
                    </td>
                </tr>

            </table> 
        </center>

        <hr />

        <!-- Display current color object. -->
        <span id="ResultId"></span>

    </body>

</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

// The page feedback display element.
var displayResult;

// This function intializes the global variables and
// assigns default values to the generated proxy.
function pageLoad() 
{
    // Get page feedback display element.
    displayResult = 
        document.getElementById("ResultId");

    // Assign default values to the generated proxy.
    Samples.AspNet.TestService.set_defaultUserContext("Default context");
    Samples.AspNet.TestService.set_defaultSucceededCallback(SucceededCallback);
    Samples.AspNet.TestService.set_defaultFailedCallback(FailedCallback);
 }

 // Get a generic List.
 function GenericList() 
 {     
    Samples.AspNet.TestService.GetGenericList(); 
 }

 // Get a generic Dictionary.
 function GenericDictionary() 
 {     
    Samples.AspNet.TestService.GetGenericDictionary(); 
 }

 // Get a generic Dictionary of custom types. 
 function GenericCustomTypeDictionary() 
 {     
    Samples.AspNet.TestService.GetGenericCustomTypeDictionary(); 
 }


 // Pass a generic dictionary of custom types
 // to Webservice.
 function PassGenericDictionary() 
 {     

    var simple = new Samples.AspNet.SimpleClass2();
    simple.s = "WebService proxy.";

    Samples.AspNet.TestService.PassGenericDictionary(
    {"first":simple}); 
 }

 // Get an Array.
 function ArrayType() 
 {     
    Samples.AspNet.TestService.GetArray(); 
 }


// Callback function invoked when the call to 
// the Web service methods succeeds. 
function SucceededCallback(result, userContext, methodName)
{ 
    var message;
    switch(methodName)
    {
        case ("GetGenericList"):
        {
            var i = 0;
            var message = new Array();
            for(var item in result)
            {    
               message[i] = "List element " + i + ": " + result[item].s;
               i++;
            }
            DisplayMessage(message.toString());
            break;
        }


        case ("GetGenericDictionary"):
        {
            var i = 0;
            var message = new Array();
            for(var item in result)
            {    
               message[i] = item + ": " + result[item];
               i++;
            }
            DisplayMessage(message.toString());
            break;
        }

        case ("GetGenericCustomTypeDictionary"):
        {
            var i = 0;
            var message = new Array();
            for(var item in result)
            {    
               message[i] = item + ": " + result[item].s;
               i++;
            }
            DisplayMessage(message.toString());
            break;
        }

        case ("PassGenericDictionary"):
        {

            DisplayMessage(result);

            break;
        }

        case ("GetArray"):
        {
            var i = 0;
            var message = new Array();
            for(var item in result)
            {    
               message[i] = result[item];
               i++;
            }
            DisplayMessage(message.toString());
            break;
        }

        default:
        {
            DisplayMessage("Method unknown");
        }
    }       
}

// Callback function invoked when the call to 
// the Web service methods fails.
function FailedCallback(error, userContext, methodName) 
{
    if(error !== null) 
    {
        displayResult.innerHTML = "An error occurred: " + 
            error.get_message();
    }
}

function DisplayMessage(message)
{
    if (document.all) 
        displayResult.innerText = message;
    else
        // Firefox
        displayResult.textContent = message;    
}



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

В следующей части примера показана вызываемая на странице веб-служба.

<%@ WebService Language="C#" Class="Samples.AspNet.TestService" %>

namespace Samples.AspNet
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Web.Services;
    using System.Web.Script.Services;

    // Custom type used by WebService.
    public class SimpleClass
    {
        private string _s = "SimpleClass1";
    
        public String s {
                    get { return _s; }
                    set { _s = value; }
        }
    }

    // Custom type used by WebService.
    public class SimpleClass2
    {
        private string _s = "SimpleClass2";

        public String s
        {
            get { return _s; }
            set { _s = value; }
        }
    }

    // The following service allows the generation
    // of the SimpleClass2 type proxy by applying the
    // attribute: GenerateScriptType. This assures
    // that the a SimpleClass2 object can be 
    // passed by the client script to the 
    // PassGenericDictionary method.
    // Note if you comment out the GenerateScriptType
    // you get an error because the SimpleClass2 type proxy
    // is not generated.
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [GenerateScriptType(typeof(SimpleClass2))]
    [ScriptService]
    public class TestService : System.Web.Services.WebService
    {
        // The following method return a list of SimpleClass
        // objects.
        // Note the SimpleClass type proxy is automatically 
        // generated because used in the return parameter.
        [WebMethod]
        [ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
        public List<SimpleClass> GetGenericList() 
        {
            List<SimpleClass> GetGenericList = new List<SimpleClass>();
            SimpleClass simple1 = new SimpleClass();
            SimpleClass simple2 = new SimpleClass();
            simple1.s = "Generics first instance";
            simple2.s = "Generics second instance";
            GetGenericList.Add(simple1);
            GetGenericList.Add(simple2);
            return GetGenericList;
        }

        // The following method return a Dictionary of strings.
        [WebMethod]
        public Dictionary<String, String> GetGenericDictionary()
        {
            //Instantiate the dictionary object.
            Dictionary<String, String> result = 
                new Dictionary<string, string>();

            //Add items.
            result.Add("0000FF", "Blue");
            result.Add("FF0000", "Red");
            result.Add("00FF00", "Green");
            result.Add("000000", "Black");

            return result;
        }

        // The following method return a Dictionary of 
        // SimpleClass objects.
        // Note the SimpleClass type proxy object is automatically 
        // generated because used in the return parameter.
        [WebMethod]
        public Dictionary<String, SimpleClass> GetGenericCustomTypeDictionary()
        {
            //Instantiate the dictionary object.
            Dictionary<String, SimpleClass> result =
                new Dictionary<string, SimpleClass>();

            SimpleClass simple = new SimpleClass();
            simple.s = "custom type instance";

            //Add items.
            result.Add("Custom type", simple);

            return result;
        }

        // The following method accept a Dictionary of 
        // SimpleClass2 objects.
        // Note the SimpleClass2 type proxy object is 
        // not automatically generated because used in 
        // an input parameter. You must enable its 
        // generation by applying the GenerateScriptType 
        // attribute to the service.
        [WebMethod]
        public String PassGenericDictionary(
            Dictionary<string, SimpleClass2> d)
        {

            string value = d["first"].s;

            string message = "Dictionary element value: " + value;

            return message;
        }


        // This function returns an array.
        [WebMethod]
        public ArrayList GetArray()
        {
            //Instantiate the array object.
            ArrayList result = new ArrayList();

            //Add items.
            result.Add("First element: " + "Test1");
            result.Add("Second element: " + "Test2");

            return result;
        }          
        
    }

}

Передача параметров, типизированных как перечислители

Для обращения к типу перечислителя можно использовать автоматически создаваемый прокси-класс.

Bb398995.alert_note(ru-ru,VS.90).gifПримечание.

Для обращения к перечислителям не следует создавать экземпляр автоматически созданного прокси-класса.

В следующем примере показан порядок вызова метода веб-службы, параметры которого типизированы как перечислители, из клиентского сценария. В первой части примера показана веб-страница, на которой выполняется вызов веб-службы с использованием клиентского сценария.

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

        <title>Using Generated Proxy Types</title>
        <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }
           .text { font: 10pt Trebuchet MS; text-align: center }
        </style>    
    </head>

    <body>

        <h2>Using Generated Proxy Types</h2>

        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="ServerTypes.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="ServerTypes.js" />
                </Scripts>
            </asp:ScriptManager>  

        </form>


        <center>
            <table style="font-size:12px;" >

                <tr align="left">
                    <td class="text">Get Enum:</td>
                    <td>
                        <button id="Button2"  
                            onclick="GetSelectedEnumValue()">Get Enum Value</button>
                    </td>
                </tr>

               <tr align="left">
                    <td class="text">Pass Enum:</td>
                    <td>
                     <button id="Button1"  
                        onclick="GetFirstEnumElement()">First Enum</button>
                    </td>
                </tr>

            </table> 
        </center>

        <hr />

        <!-- Display current color object. -->
        <span id="ResultId"></span>

    </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">

        <title>Using Generated Proxy Types</title>
        <style type="text/css">
            body {  font: 11pt Trebuchet MS;
                    font-color: #000000;
                    padding-top: 72px;
                    text-align: center }
           .text { font: 10pt Trebuchet MS; text-align: center }
        </style>    
    </head>

    <body>

        <h2>Using Generated Proxy Types</h2>

        <form id="form1" runat="server">

            <asp:ScriptManager runat="server" ID="scriptManager">
                <Services>
                    <asp:ServiceReference Path="ServerTypes.asmx" />
                </Services>
                <Scripts>
                    <asp:ScriptReference Path="ServerTypes.js" />
                </Scripts>
            </asp:ScriptManager>  

        </form>


        <center>
            <table style="font-size:12px;" >

                <tr align="left">
                    <td class="text">Get Enum:</td>
                    <td>
                        <button id="Button2"  
                            onclick="GetSelectedEnumValue()">Get Enum Value</button>
                    </td>
                </tr>

               <tr align="left">
                    <td class="text">Pass Enum:</td>
                    <td>
                     <button id="Button1"  
                        onclick="GetFirstEnumElement()">First Enum</button>
                    </td>
                </tr>

            </table> 
        </center>

        <hr />

        <!-- Display current color object. -->
        <span id="ResultId"></span>

    </body>

</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

// ServerTypes.js

// The Web service default color.
var defaultRgb;

// The page feedback display element.
var displayResult;

// Gets the Web service selection list colors 
// and the default color.
function pageLoad() 
{
    // Get page feedback display element.
    displayResult = 
        document.getElementById("ResultId");

    // Assign default values for the generated proxy using
    // the (generated) static proxy.
    Samples.AspNet.ServerTypes.set_timeout(200);
    Samples.AspNet.ServerTypes.set_defaultUserContext("Default context");
    Samples.AspNet.ServerTypes.set_defaultSucceededCallback(SucceededCallback);
    Samples.AspNet.ServerTypes.set_defaultFailedCallback(FailedCallback);

}

// This function shows how to get an 
// enumeration object from the server.
function GetFirstEnumElement()
{
    // Get the first element of the enumeration
    Samples.AspNet.ServerTypes.GetFirstColor();
}

// This function shows how to pass an 
// enumeration value to the server.
function GetSelectedEnumValue()
{
   // Get the value of the selected enumerated
   // element.
   Samples.AspNet.ServerTypes.GetSelectedColor(
    Samples.AspNet.ColorEnum.Blue);
}

// Callback function invoked when the call to 
// the Web service methods succeeds.
function SucceededCallback(result, userContext, methodName)
{ 
    var message;
    switch(methodName)
    {
        case ("GetFirstColor"):
        {
            var firstColor = result;
            message = "First enumerated value: " + firstColor;
            DisplayMessage(message);
            break;
        }

        default:
        {
            DisplayMessage("Method unknown");
        }
    }       
}

// Callback function invoked when the call to 
// the Web service methods fails.
function FailedCallback(error, userContext, methodName) 
{
    if(error !== null) 
    {
        displayResult.innerHTML = "An error occurred: " + 
            error.get_message();
    }
}

function DisplayMessage(message)
{
    if (document.all) 
        displayResult.innerText = message;
    else
        // Firefox
        displayResult.textContent = message;    
}



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

В следующей части примера показана вызываемая на странице веб-служба.

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

Imports System
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Web.Script.Services
Imports System.Web.Script.Serialization
Imports System.Collections.Generic

Namespace Samples.AspNet

    ' Define the enum type to
    ' exchange with the client.
    Public Enum ColorEnum
        Red = 0
        Green = 1
        Blue = 2
    End Enum

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

        ' The enum type can be accessed by the client
        ' script through the generated Web service
        ' proxy class in a static fashion.
        <WebMethod()> _
        Public Function GetFirstColor() As ColorEnum
            ' Return the first color
            ' in the enumeration.
            Return ColorEnum.Red

        End Function

        <WebMethod()> _
        Public Function GetSelectedColor(ByVal color As ColorEnum) As String
            ' Return the selected color value
            ' in the enumeration.
            Return color.ToString()

        End Function

    End Class

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

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
using System.Web.Script.Serialization;
using System.Collections.Generic;

namespace Samples.AspNet
{


    // Define the enum type to
    // exchange with the client.
    public enum ColorEnum
    {
        Red     = 0,
        Green   = 1,
        Blue    = 2
    }        

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

        // The enum type can be accessed by the client
        // script through the generated Web service
        // proxy class in a static fashion.
        [WebMethod]
        public ColorEnum GetFirstColor()
        {
            // Return the first color
            // in the enumeration.
            return ColorEnum.Red;
        }

        [WebMethod]
        public string GetSelectedColor(ColorEnum color)
        {
            // Return the selected color value
            // in the enumeration.
            return color.ToString();
        }

    }

}

Вызов операций службы WCF

Windows Communication Foundation (WCF) представляет собой унифицированную модель программирования корпорации Майкрософт, предназначенную для построения ориентированных на службы приложений. В этой модели поддерживаются функции AJAX ASP.NET и формат данных JSON. Благодаря этому поддерживается использование операций служб WCF веб-страницами, на которых выполняется код JavaScript, за счет чего обеспечивается доступ к этим службам с помощью HTTP-запросов.

Если службы WCF уже созданы, можно добавить конечные точки, чтобы разрешить доступ к этим службам из сценария, содержащегося на веб-странице с поддержкой AJAX.

Вызов операции службы Windows Communication Foundation (WCF) (термин «операция» соответствует понятию метода в WCF) из сценария осуществляется асинхронным способом. Как и для других асинхронных процедур, следует определить функцию обратного вызова, которая вызывается при успешном выполнении запроса. Также можно определить функцию обратного вызова при неудачном завершении запроса, используемую для обработки ошибок. Дополнительные сведения о службах Windows Communication Foundation (WCF) и порядке их размещения в ASP.NET см. на веб-узле ASP.NET AJAX Integration and JSON Support.

В следующем примере показан порядок построения службы WCF и вызова ее методов с использованием клиентского сценария в сценарии веб-страницы. В первой части примера показан порядок вызова службы с использованием клиентского сценария.

<%@ Page Language="VB" AutoEventWireup="true" %>

<!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 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 WCF Service Page</title>

</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Services>
                <asp:ServiceReference 
                    Path="SimpleService.svc/ws"/>
            </Services>
            <Scripts>
                <asp:ScriptReference Path="service.js" />
            </Scripts>
        </asp:ScriptManager>
        
        <div>
            <h2>Simple WCF Service</h2>
            <input type='button' name="clickme"  value="Greetings" 
                onclick="javascript:OnClick()" /> &nbsp; &nbsp;
            <input type='button' name="clickme2"  value="Greetings2" 
                onclick="javascript:OnClick2()" />
            <hr/>
            <div>
                <span id="Results"></span>
            </div> 
        </div>

    </form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true"%>

<!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 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 WCF Service Page</title>

</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Services>
                <asp:ServiceReference 
                    Path="SimpleService.svc/ws"/>
            </Services>
            <Scripts>
                <asp:ScriptReference Path="service.js" />
            </Scripts>
        </asp:ScriptManager>
        
        <div>
            <h2>Simple WCF Service</h2>
            <input type='button' name="clickme"  value="Greetings" 
                onclick="javascript:OnClick()" /> &nbsp; &nbsp;
            <input type='button' name="clickme2"  value="Greetings2" 
                onclick="javascript:OnClick2()" />
            <hr/>
            <div>
                <span id="Results"></span>
            </div> 
        </div>

    </form>
</body>
</html>

В следующей части примера показан клиентский сценарий веб-страницы, который используется для вызова веб-службы.

var ServiceProxy;

function pageLoad()
{
    ServiceProxy = new ISimpleService();
    ServiceProxy.set_defaultSucceededCallback(SucceededCallback);
}

function OnClick()
{
    // var myService = new ISimpleService();
    ServiceProxy.HelloWorld1("George");
}

function OnClick2()
{
    var dc = new DataContractType();
    dc.FirstName = "George";
    dc.LastName = "Washington";
    ServiceProxy.HelloWorld2(dc);      
}

// This is the callback function that
// processes the Web Service return value.
function SucceededCallback(result, userContext, methodName)
{
    var RsltElem = document.getElementById("Results");
    RsltElem.innerHTML = result + " from " + methodName + ".";
}
if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

В следующей части примера показана вызываемая на странице веб-служба.

Imports System
Imports System.Web
Imports System.Collections
Imports System.Collections.Generic
Imports System.Threading
Imports System.Xml
Imports System.Xml.Serialization
Imports System.Text
Imports System.IO
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Activation


' This a WCF service which consists of a contract, 
' defined below as ISimpleService, and DataContractType, 
' a class which implements that interface, see SimpleService, 
' and configuration entries that specify behaviors associated with 
' that implementation (see <system.serviceModel> in web.config)
Namespace Aspnet.Samples.SimpleService

    <ServiceContract()> _
    Public Interface ISimpleService
        <OperationContract()> _
        Function HelloWorld1(ByVal value1 As String) As String
        <OperationContract()> _
        Function HelloWorld2(ByVal dataContractValue1 _
        As DataContractType) As String
    End Interface 'ISimpleService

    <ServiceBehavior(IncludeExceptionDetailInFaults:=True), _
    AspNetCompatibilityRequirements(RequirementsMode:= _
    AspNetCompatibilityRequirementsMode.Allowed)> _
    Public Class SimpleService
        Implements ISimpleService

        Public Sub New()

        End Sub 'New

        Public Function HelloWorld1(ByVal value1 As String) As String _
        Implements ISimpleService.HelloWorld1
            Return "Hello " + value1
        End Function 'HelloWorld1

        Public Function HelloWorld2(ByVal dataContractValue1 _
        As DataContractType) As String _
        Implements ISimpleService.HelloWorld2
            Return "Hello " + dataContractValue1.FirstName + " " + _
            dataContractValue1.LastName
        End Function 'HelloWorld2
    End Class 'SimpleService

    <DataContract()> _
    Public Class DataContractType
        Private _firstName As String
        Private _lastName As String


        <DataMember()> _
        Public Property FirstName() As String
            Get
                Return _firstName
            End Get
            Set(ByVal value As String)
                _firstName = value
            End Set
        End Property

        <DataMember()> _
        Public Property LastName() As String
            Get
                Return _lastName
            End Get
            Set(ByVal value As String)
                _lastName = value
            End Set
        End Property
    End Class 'DataContractType 
End Namespace

using System;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel.Activation;

// This a WCF service which consists of a contract, 
// defined below as ISimpleService, and DataContractType, 
// a class which implements that interface, see SimpleService, 
// and configuration entries that specify behaviors associated with 
// that implementation (see <system.serviceModel> in web.config)

namespace Aspnet.Samples
{
    [ServiceContract()]
    public interface ISimpleService
    {
        [OperationContract]
        string HelloWorld1(string value1);
        [OperationContract]
        string HelloWorld2(DataContractType dataContractValue1);
    }

    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class SimpleService : ISimpleService
    {
        public SimpleService()
        { }

        public string HelloWorld1(string value1)
        {
            return "Hello " + value1;
        }
        public string HelloWorld2(DataContractType dataContractValue1)
        {
            return "Hello " + dataContractValue1.FirstName +
                                " " + dataContractValue1.LastName;
        }
    }

    [DataContract]
    public class DataContractType
    {
        string firstName;
        string lastName;

        [DataMember]
        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }
        [DataMember]
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }
    }

}

См. также

Задачи

Использование элемента управления UpdatePanel c веб-службой

Основные понятия

Использование веб-служб в технологии AJAX ASP.NET

Использование веб-служб в технологии AJAX ASP.NET

Предоставление доступа к службам WCF в клиентском сценарии

Предоставление доступа к веб-службам в клиентском сценарии