Вы находитесь на странице: 1из 43

The ASP.

NET AJAX
Extensions
Jeff Prosise
Cofounder, Wintellect
www.wintellect.com
Architecture
ASPX ASMX

ASP.NET AJAX Extensions

Application Services
Bridge
Server
Controls
Asynchronous
Communications

ASP.NET 2.0

Page Framework Application


& Server Controls Services
Server Controls
Script Partial-Page
Management Rendering Futures CTP

DragOverlay-
ScriptManager UpdatePanel
Extender

ScriptManager- Update-
Proxy Progress ProfileService

Timer
ScriptManager
Starting point for ASP.NET AJAX pages
What does ScriptManager do?
Downloads JavaScript files to client
Enables partial-page rendering using
UpdatePanel
Provides access to Web services via
client-side proxies
Manages callback timeouts, provides
error handling options and infrastructure,
and more
Every page requires one
ScriptManager Schema
<asp:ScriptManager ID="ScriptManager1" Runat="server"
EnablePartialRendering="true|false"
EnablePageMethods="true|false"
AsyncPostBackTimeout="seconds"
AsyncPostBackErrorMessage="message"
AllowCustomErrorsRedirect="true|false"
OnAsyncPostBackError="handler"
EnableScriptGlobalization="true|false"
EnableScriptLocalization="true|false"
ScriptMode="Auto|Inherit|Debug|Release"
ScriptPath="path">
<Scripts>
<!-- Declare script references here -->
</Scripts>
<Services>
<!-- Declare Web service references here -->
</Services>
</asp:ScriptManager>
Script References
"Name" references load script resources

<asp:ScriptManager ID="ScriptManager1" Runat="server">


<Scripts>
<asp:ScriptReference Name="PreviewScript.js"
Assembly="Microsoft.Web.Preview" />
<asp:ScriptReference Name="PreviewDragDrop.js"
Assembly="Microsoft.Web.Preview" />
<asp:ScriptReference Path="~/Scripts/UIMap.js" />
</Scripts>
</asp:ScriptManager>

"Path" references load script files


Service References
<asp:ScriptManager ID="ScriptManager1" Runat="server">
<Services>
<asp:ServiceReference Path="ZipCodeService.asmx" />
</Services>
</asp:ScriptManager>
ScriptManagerProxy
"Proxy" for ScriptManager controls
declared in master pages
Lets content pages declare script and
service references

<asp:ScriptManagerProxy ID="ScriptManagerProxy1" Runat="server">


<Scripts>
<!-- Declare additional script references here -->
</Scripts>
<Services>
<!-- Declare additional service references here -->
</Services>
</asp:ScriptManagerProxy>
UpdatePanel
Partial-page rendering in a box
Clean round trips to server and updates
Requires no knowledge of JavaScript or
AJAX
Leverages PageRequestManager
class
EnablePartialRendering="true"
Supports explicitly defined triggers
Postbacks from controls in UpdatePanel
are converted into async callbacks
Triggers expand (or shrink) postback-
UpdatePanel Schema
<asp:ScriptManager ID="ScriptManager1" Runat="server"
EnablePartialRendering="true" />
.
.
.
<asp:UpdatePanel ID="UpdatePanel1" Runat="server"
UpdateMode="Always|Conditional"
ChildrenAsTriggers="true|false">
<Triggers>
<!-- Define triggers (if any) here -->
</Triggers>
<ContentTemplate>
<!-- Define content here -->
</ContentTemplate>
</asp:UpdatePanel>
Triggers
AsyncPostBackTrigger
Converts postbacks into async callbacks
Typically used to trigger updates when
controls outside an UpdatePanel post
back
If ChildrenAsTriggers="false", can be
used to specify which controls inside
UpdatePanel should call back rather than
post back
PostBackTrigger
Lets controls inside UpdatePanel post
back
Triggers Example
<asp:UpdatePanel ID="UpdatePanel1" Runat="server"
UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
<asp:AsyncPostBackTrigger ControlID="TreeView1"
EventName="TreeNodeExpanded" />
<asp:AsyncPostBackTrigger ControlID="TreeView1"
EventName="TreeNodeCollapsed" />
<asp:PostBackTrigger ControlID="Button2" />
</Triggers>
<ContentTemplate>
...
</ContentTemplate>
</asp:UpdatePanel>
Periodic Updates
Combine UpdatePanel with Timer
control to perform periodic updates
Use Timer control Tick events as
triggers
<asp:Timer ID="Timer1" Runat="server" Interval="5000"
OnTick="OnTimerTick" />
...
<asp:UpdatePanel UpdateMode="Conditional" ...>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" />
</Triggers>
...
</asp:UpdatePanel>
Demo
UpdateProgress
Companion to UpdatePanel controls
Displays custom template-driven UI
for:
Indicating that an async update is in
progress
Canceling an async update that is in
progress
Automatically displayed when update
begins or "DisplayAfter" interval
elapses
UpdateProgress Schema
<asp:UpdateProgress ID="UpdateProgress1" Runat="server"
DisplayAfter="milliseconds"
DynamicLayout="true|false"
AssociatedUpdatePanelID="UpdatePanelID">
<ProgressTemplate>
<!-- Declare UpdateProgress UI here -->
</ProgressTemplate>
</asp:UpdateProgress>
UpdateProgress Example
Display after ½ second

<asp:UpdateProgress DisplayAfter="500" ...>


<ProgressTemplate>
<asp:Image ID="ProgressImage" Runat="server"
ImageUrl="~/Images/SpinningClock.gif" />
</ProgressTemplate>
</asp:UpdateProgress>

Animated GIF
Canceling an Update
<asp:UpdateProgress DisplayAfter="500" ...>
<ProgressTemplate>
<b>Working...</b>
<asp:Button ID="CancelButton" Runat="server" Text="Cancel"
OnClientClick="cancelUpdate(); return false" />
</ProgressTemplate>
</asp:UpdateProgress>

<script type="text/javascript">
function cancelUpdate()
{
var obj = Sys.WebForms.PageRequestManager.getInstance();
if (obj.get_isInAsyncPostBack())
obj.abortPostBack();
}
</script>
Demo
ASP.NET AJAX Web Services
ASP.NET AJAX supports ASMX Web
methods as endpoints for
asynchronous AJAX callbacks
Efficient on the wire (no SOAP or XML)
Efficient on the server (no page lifecycle)
ScriptService attribute on server
indicates Web service is callable from
script
JavaScript proxy on client enables
JavaScript clients to call Web
methods
Script-Callable Web
Service
[System.Web.Script.Services.ScriptService]
public class ZipCodeService : System.Web.Services.WebService
{
[System.Web.Services.WebMethod]
public string[] GetCityAndState (string zip)
{
...
}
}
Declaring a Service
Reference
<asp:ScriptManager ID="ScriptManager1" Runat="server">
<Services>
<asp:ServiceReference Path="ZipCodeService.asmx" />
</Services>
</asp:ScriptManager>

<script src="ZipCodeService.asmx/js" type="text/javascript">


</script>
Consuming a Web Service
ZipCodeService.GetCityAndState("98052", onCompleted);
.
.
.
function onCompleted (result)
{
window.alert(result);
}
Handling Errors
ZipCodeService.GetCityAndState("98052", onCompleted, onFailed);
.
.
.
function onCompleted (result, context, methodName)
{
window.alert(result);
}

function onFailed (err, context, methodName)


{
window.alert(err.get_message());
}
Demo
ASMX Wire Format
Request
POST /AtlasRC/ZipCodeService.asmx/GetCityAndState HTTP/1.1
Accept: */*
Accept-Language: en-us
Referer: http://localhost:1997/AtlasRC/ZipCodePage.aspx
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; ...)
Host: localhost:1997
Content-Length: 15
Connection: Keep-Alive
Cache-Control: no-cache

{"zip":"98052"}

Response
HTTP/1.1 200 OK
JSON-encoded Server: ASP.NET Development Server/8.0.0.0
Date: Fri, 29 Dec 2006 21:06:17 GMT
input X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: application/json; charset=utf-8
JSON-encoded Content-Length: 16
Connection: Close
output
["REDMOND","WA"]
ScriptHandlerFactory
Wraps default ASP.NET ASMX handler
<httpHandlers>
<remove verb="*" path="*.asmx" />
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, ..." />
</httpHandlers>

Extends ASMX model with "special"


URLs
JavaScript proxy generation (*.asmx/js)
Calls to Web methods
(*.asmx/methodname)
ASMX Request Handling
ASMX Extensions

RestClient-
*.asmx *.asmx/js
ProxyHandler
ScriptHandler- Helper
Factory Classes

*.asmx/methodname RestHandler

"Normal" ASMX calls

WebService-
HandlerFactory Default ASMX handler
JSON
JavaScript Object Notation
Lightweight data interchange format
Easier to read and write than XML
Based on subset of JavaScript
Default interchange format in
ASP.NET AJAX
Microsoft.Web.Script.-
Serialization.JavaScriptSerializer (server)
Sys.Serialization.JavaScriptSerializer
(client)
JSON home page: www.json.org
JSON vs. XML
Point p = new Point(100, 200);

JSON
{"IsEmpty":false,"X":100,"Y":200}

XML
<?xml version="1.0"?>
<Point xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<X>100</X>
<Y>200</Y>
</Point>
The ScriptMethod
Attribute
Optional attribute for script-callable
Web methods
Offers added control over wire format
of calls
Property Description

UseHttpGet True = Use HTTP GET, False = Use HTTP POST (default)

ResponseFormat ResponseFormat.Xml or ResponseFormat.Json (default)

XmlSerializeString True = Serialize everything (including strings) as XML,


False = Serialize response strings as JSON (default)
(Only valid if ResponseFormat == ResponseFormat.Xml)
Using ScriptMethod
[System.Web.Script.Services.ScriptService]
public class ZipCodeService : System.Web.Services.WebService
{
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod
(ResponseFormat=ResponseFormat.Xml)]
public XmlDocument GetCityAndState (string zip)
{
...
}
}

Method returns XML document, so serialize as


XML rather than JSON
Page Methods
Script-callable Web methods in pages
Simpler than full-blown Web services
Do not require service references
Do not require dedicated ASMX files
Must be public static methods
Must be enabled via ScriptManager.-
EnablePageMethods (disabled by
default)
Called through PageMethods proxy
on client
Enabling Page Methods
<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true"
Runat="server" />

var PageMethods = function() {


PageMethods.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
PageMethods.prototype = {
...
}
Defining a Page Method
public partial class MyPage : System.Web.UI.Page
{
[System.Web.Services.WebMethod]
public static string[] GetCityAndState (string zip)
{
...
}
...
}
Calling a Page Method
PageMethods.GetCityAndState("98052", onComplete);
.
.
.
function onComplete(result)
{
window.alert(result);
}
Demo
Built-In Web Services
AuthenticationService
Front end to membership service
Sys.Services.AuthenticationService proxy
Global instance of
Sys.Services._AuthenticationService
ProfileService
Front-end to profile service
Sys.Services.Profile proxy
Global instance of
Sys.Services._ProfileService
Accessed through
Using
AuthenticationService
Sys.Services.AuthenticationService.login (username, password,
false, null, null, onLoginCompleted, onLoginFailed);
...
function onLoginCompleted(result, context, methodName)
{
window.alert(result ? 'Login succeeded' : 'Login failed');
}

function onLoginFailed(err, context, methodName)


{
window.alert(err.get_message());
}
Loading Profile Properties
Pass null to load all profile properties

Sys.Services.ProfileService.load(['ScreenName'], onLoadCompleted,
onLoadFailed);
...
function onLoadCompleted(result, context, methodName)
{
window.alert(Sys.Services.ProfileService.properties.ScreenName);
}

function onLoadFailed(err, context, methodName)


{
window.alert(err.get_message());
}
Saving Profile Properties
Pass null to save all profile properties

Sys.Services.ProfileService.properties.ScreenName = 'Bob';
Sys.Services.ProfileService.save(['ScreenName'], onSaveCompleted,
onSaveFailed);
...
function onSaveCompleted(result, context, methodName)
{
window.alert('Save succeeded');
}

function onSaveFailed(err, context, methodName)


{
window.alert(err.get_message());
}

Вам также может понравиться