Using Web Services in ASP.NET AJAX

This topic describes how to access Web services from client script in AJAX-enabled ASP.NET Web pages. The services can be either custom services that you create, or built-in application services. The application services are provided as part of ASP.NET AJAX, and include authentication, roles, and profile services.

Custom Web services can be in the form of .ASP.NET Web services (.asmx services), or Windows Communication Foundation (WCF) services (.svc services).

This topic contains the following information:

  • Scenarios

  • Background

  • Examples

  • Additional Resources

  • Class Reference

  • What's New

Scenarios

You use WCF and ASP.NET in the following cases:

  • If you have already created WCF services, you can add endpoints to enable script in AJAX-enabled Web pages to access the services. For more information, see Exposing WCF Services to Client Script.

  • If you have already created ASP.NET Web (.asmx) services, you can modify them to enable script in AJAX-enabled Web pages to access the same service. For more information, see Exposing Web Services to Client Script.

  • If you want to create a custom Web service that will be accessed from ASP.NET AJAX Web pages, you can implement it as a WCF service or as an ASP.NET Web service (.asmx file).

  • You can use the built-in ASP.NET application services to access users' authentication, roles, and profile information from client script that runs in an AJAX-enabled Web page. For more information, see Using Forms Authentication with ASP.NET AJAX.

Background

ASP.NET enables you to create Web services can be accessed from client script in Web pages. The pages communicate with the server through a Web service communication layer that uses AJAX technology to make Web service calls. Data is exchanged asynchronously between client and server, typically in JSON format.

Client-Server Communication for AJAX Clients

In AJAX-enabled Web pages, the browser makes an initial request to the server for the page, and then makes subsequent asynchronous requests to Web services for data. The client communication elements are in the form of downloaded proxy classes from the server and the core client-script library. The server communication elements are handlers and custom services. The following illustration shows the elements that are involved in the communication between the client and the server.

Client Server Communication

Web Services Client Server Communication in AJAX

AJAX Client Architecture

Browsers call Web service methods by using proxy classes. A proxy class is a script that is automatically generated by the server and downloaded to the browser at page-load time. The proxy class provides a client object that represents the exposed methods of a Web service.

To call a Web service method, client script calls the corresponding methods of the proxy class. The calls are made asynchronously, through the XMLHTTP object.

The Web service communication layer contains the library script types that enable the proxy classes to make service calls. For more information, see the classes that are contained in the Sys.Net namespace.

The code in the proxy classes and in the core Web service communication layer hides the complexity of XMLHTTP and the differences between browsers. This simplifies the client script that is required to call the Web service.

There are two approaches to making a Web service request:

  • Call Web services by using the HTTP POST verb. A POST request has a body that contains the data that the browser sends to the server. It does not have a size limitation. Therefore, you can use a POST request when the size of the data exceeds the intrinsic size limitation for a GET request. The client serializes the request into JSON format and sends it as POST data to the server. The server deserializes the JSON data into .NET Framework types and makes the actual Web service call. During the response, the server serializes the return values and passes them back to the client, which deserializes them into JavaScript objects for processing.

  • Call Web services by using the HTTP GET verb. This resembles the functionality of a POST request, with the following differences:

    • The client uses a query string to send the parameters to the server.

    • A GET request can call only a Web service method that is configured by using the ScriptMethodAttribute attribute.

    • Data size is limited to the URL length allowed by the browser.

      Note

      GET requests should be avoided for method calls that modify data on the server or that expose critical information. In GET requests, the message is encoded by the browser into the URL and is therefore an easier target for tampering. For both GET and POST requests, you should follow security guidelines to protect sensitive data.

The following illustration shows the ASP.NET AJAX client architecture.

AJAX Client Architecture

Web Services Client Architecture in AJAX

Elements of the client architecture include the Web service communication layer in the core library and the downloaded proxy classes for the services that are used on the page. Individual elements shown in the figure are as follows:

  • Custom Service Proxy Classes. These consist of client script that is automatically generated by the server and downloaded to the browser. The proxy classes provide an object for each WCF or ASMX service that is used in the page. (That is, they provide an object for each item in the ServiceReferences element of the ScriptManager control in the page.) Calling a proxy method in client script creates an asynchronous request to the corresponding Web service method on the server.

  • Authentication Proxy Class. The AuthenticationService proxy class is generated by the server authentication application service. It enables the user to log on or log out through JavaScript in the browser without making a round trip to the server.

  • Role Proxy Class. The RoleService proxy class is generated by the server roles application service. It enables you to group users and treat each group as a unit through JavaScript without making round trips to the server. This can be useful to enable or deny access to resources on the server.

  • Profile Proxy Class. The ProfileService class is generated by the server profile application service. It makes the current user's profile information available to the client through JavaScript without making round trips to the server.

  • Page Methods Proxy Class. This provides the scripting infrastructure for client script to call static methods in an ASP.NET page as if they were Web service methods. For more information, see Calling Web Services from Client Script.

  • Web Service Communication Layer. This is the library that contains the client script types. These types enable the browser (client) to communicate with the services on the server. They also shield client applications from the complexities of establishing and maintaining the asynchronous communication between client and server. They encapsulate the browser XMLHTTP object that provides the asynchronous capability, and enable client applications to be browser independent. The following are the main elements of the Web service communication layer:

    • WebRequest. This provides client script functionality to make a Web request. For more information, see the WebRequest class.

    • WebRequestManager. This manages the flow of the Web requests issued by the WebRequest object to the associated executor object. For more information, see the WebRequestManager class.

    • XmlHttpExecutor. This makes asynchronous network requests by using the browser's XMLHTTP support. For more information, see the XmlHttpExecutor class.

    • JSON Serialization. This serializes JavaScript objects into JSON format. Deserialization is available by using the JavaScript eval function. For more information, see the JavaScriptSerializer class.

The default serialization format is JSON, but individual methods in Web services and in ASP.NET Web pages can return alternative formats such as XML. The serialization format of a method can be specified with attributes. For example, for an ASMX service, you can set the ScriptMethodAttribute attribute to cause a Web service method to return XML data, as shown in the following example:

[ScriptMethod(ResponseFormat.Xml)] 
<ScriptMethod(ResponseFormat.Xml)> 

AJAX Server Architecture

The following illustration shows the AJAX server architecture, which includes the elements that enable communication with client applications.

AJAX Server Architecture

Web Services Server Architecture in AJAX

Elements of the server architecture include the Web service communication layer with a HTTP handler and serialization classes, custom services, page methods, and application services. Individual elements shown in the figure are as follows:

  • Custom Web Services. These provide the service functionality that you implement and return the appropriate response to the client. Custom Web services can be ASP.NET or WCF services. The Web service communication layer automatically generates client-script proxy classes that can be called asynchronously from client script.

  • Page Methods. This component enables a method in an ASP.NET page to be called as if it were a Web service method. Page methods must be defined in the page that is performing the page-method call.

  • Authentication Service. The authentication service generates an authentication proxy class that enables the user to log on or log out through client JavaScript. This application service is always available and you do not have to instantiate it. For more information, see Using Forms Authentication with ASP.NET AJAX.

  • Role Service. The role service generates a role proxy class that enables client JavaScript to access roles information for the currently authenticated user. This application service is always available and you do not have to instantiate it. For more information, see Using Roles Information with ASP.NET AJAX.

  • Profile Service. The profile service generates a profile proxy class that enables client JavaScript to get and set profile properties for the user that is associated with the current request. This application service is always available and you do not have to instantiate it. For more information, see Using Profile Information with ASP.NET AJAX.

  • JSON Serialization. The server JSON serialization component enables customizable serialization and deserialization of common .NET Framework types to and from JSON format. For more information, see JavaScriptSerializer.

  • XML Serialization. The Web service communication layer supports XML serialization for SOAP requests to Web services and for returning XML types from a JSON request to a Web service.

Examples

The following examples show how to call ASP.NET and WCF services from client script. Examples of how to call application services from client script are provided in other sections of the documentation. The related links are provided later in this topic.

Calling Web Service Methods in AJAX

The .NET Framework enables you to call ASP.NET Web services (.asmx) methods from the browser asynchronously by using client script. The page can call server-based methods without a postback and without refreshing the whole page, because only data is transferred between the browser and the server.

This following example shows how to expose a Web service method in an ASP.NET Web page.

<%@ 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 GetServerTime()
            {
                Samples.AspNet.ServerTime.GetServerTime(OnSucceeded);
            }

            // This is the callback function that
            // processes the Web Service return value.
            function OnSucceeded(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="ServerTime.asmx" />
                </Services>
            </asp:ScriptManager>
            <div>
                <h2>Server Time</h2>
                    <p>Calling a service that returns the current server time.</p>

                    <input id="EchoButton" type="button" 
                        value="GetTime" onclick="GetServerTime()" />
            </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 GetServerTime()
            {
                Samples.AspNet.ServerTime.GetServerTime(OnSucceeded);
            }

            // This is the callback function that
            // processes the Web Service return value.
            function OnSucceeded(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="ServerTime.asmx" />
                </Services>
            </asp:ScriptManager>
            <div>
                <h2>Server Time</h2>
                    <p>Calling a service that returns the current server time.</p>

                    <input id="EchoButton" type="button" 
                        value="GetTime" onclick="GetServerTime()" />
            </div>
        </form>

        <hr/>

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

    </body>

</html>

The following example shows a Web page and the related Web service called by the page script.

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

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

        <WebMethod()> _
        Public Function GetServerTime() As String
            Return String.Format("The current time is {0}.", _
                DateTime.Now)

        End Function
    End Class

End Namespace

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

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

        [WebMethod]
        public string GetServerTime()
        {
            return String.Format("The server time is {0}.", 
                DateTime.Now);

        }

    }

}

Making HTTP Requests from an AJAX Client

The previous example shows how to call Web services from client script by calling the automatically generated proxy classes for the Web service. You can also make lower-level calls to Web services from client script. You might do this if you have to manage the communication layer or examine the data that is being sent to or from the server. To call Web services in this manner, you use the WebRequest class.

The following example shows how to use a WebRequest object to implement GET and POST Web requests that connect to the specified URLs (HTTP end points).

Calling WCF Service Operations in AJAX

You can call Windows Communication Foundation (WCF) services (.svc) asynchronously from client script basically like you call .asmx-based services. This following example shows how to expose and call WCF service operations in an ASP.NET Web page.

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

}

Additional Examples

Back to top

Class Reference

The following tables list the main classes that are associated with Web services that can be called from client script.

Client Namespaces

Name

Description

Sys.Net Namespace

Contains classes that manage communication between ASP.NET AJAX client applications and Web services on the server. The Sys.Net namespace is part of the Microsoft AJAX Library.

Sys.Serialization Namespace

Contains classes that are related to data serialization for ASP.NET AJAX client applications.

Sys.Services Namespace

Contains types that provide script access in ASP.NET AJAX client applications to the ASP.NET authentication service, profile service, and other application services. The Sys.Services namespace is part of the Microsoft AJAX Library.

Server Namespaces

Name

Description

System.Web.Script.Serialization

Contains classes that provide JavaScript Object Notation (JSON) serialization and deserialization for managed types. It also provides extensibility features to customize serialization behavior.

Back to top

Additional Resources

About Native XMLHTTP

http://www.json.org

What is the Windows Communication Foundation?

XML Web Services Infrastructure

WCF Services and ASP.NET

Understanding Service-Oriented Architecture

What's New

The following are new features in ASP.NET version 3.0:

  • Application services in Windows Communication Foundation (WCF).

  • Application services in AJAX called from a .NET Framework client application.

Back to top

See Also

Tasks

Walkthrough: Creating and Using AJAX-Enabled Web Service

Concepts

Using Forms Authentication with ASP.NET AJAX

ASP.NET Application Services Overview