ArchitectureArchitecture
ASP.NET 2.0
Page Framework & Server Controls
Page Framework & Server Controls
ApplicationServices
ApplicationServices
ASP.NET AJAX Extensions
ServerControls
ServerControls
ASPXASPX ASMXASMX
Application ServicesBridge
Application ServicesBridge
AsynchronousCommunications
AsynchronousCommunications
Server ControlsServer Controls
UpdatePanelUpdatePanel
Update-Progress
Update-Progress
TimerTimer
DragOverlay-Extender
DragOverlay-ExtenderScriptManagerScriptManager
ScriptManager-Proxy
ScriptManager-Proxy ProfileServiceProfileService
ScriptManagement
Partial-Page Rendering Futures CTP
ScriptManagerScriptManager
• 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 and provides error
handling options and infrastructure– Provides registration methods for scripts– Enables ASP.NET AJAX localization support
• Every page requires one ScriptManager instance!
ScriptManager SchemaScriptManager 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 ReferencesScript References
<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
"Name" references load script resources
Service ReferencesService References
<asp:ScriptManager ID="ScriptManager1" Runat="server"> <Services> <asp:ServiceReference Path="ZipCodeService.asmx" /> </Services></asp:ScriptManager>
ScriptManagerProxyScriptManagerProxy
• "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>
UpdatePanelUpdatePanel
• Partial-page rendering in a box– Clean round trips to server and flicker-free updates– Requires no knowledge of JavaScript or AJAX
• Leverages client-side PageRequestManager class– EnablePartialRendering="true" in ScriptManager
• Supports explicitly defined triggers– By default, postbacks from all controls in an
UpdatePanel are converted into async callbacks– Triggers expand (or shrink) postback->callback
scope
• Works in virtually all scenarios
UpdatePanel SchemaUpdatePanel 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>
TriggersTriggers
• AsyncPostBackTrigger– Converts postbacks into asynchronous callbacks– Typically used to trigger updates when controls
outside an UpdatePanel post back and fire events– If ChildrenAsTriggers="false", can be used to
specify which controls inside UpdatePanel should call back rather than post back
• PostBackTrigger– Allows controls inside an UpdatePanel to post back– Typically used to allow certain controls to post
back when ChildrenAsTriggers="true"
Triggers ExampleTriggers 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 UpdatesPeriodic Updates
• Combine UpdatePanel with Timer control to implement pages that 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>
UpdatePanel
UpdateProgressUpdateProgress
• 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 SchemaUpdateProgress Schema
<asp:UpdateProgress ID="UpdateProgress1" Runat="server" DisplayAfter="milliseconds" DynamicLayout="true|false" AssociatedUpdatePanelID="UpdatePanelID"> <ProgressTemplate> <!-- Declare UpdateProgress UI here --> </ProgressTemplate></asp:UpdateProgress>
UpdateProgress ExampleUpdateProgress Example
<asp:UpdateProgress DisplayAfter="500" ...> <ProgressTemplate> <asp:Image ID="ProgressImage" Runat="server" ImageUrl="~/Images/SpinningClock.gif" /> </ProgressTemplate></asp:UpdateProgress>
Animated GIF
Display after ½ second
Canceling an UpdateCanceling 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>
UpdateProgress
ASP.NET AJAX Web ServicesASP.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 client-side script
• JavaScript proxy on client enables JavaScript clients to call Web methods on server– Proxies generated by service references
• WCF support coming in future release
Script-Callable Web ServiceScript-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 Declaring a Service ReferenceReference<asp:ScriptManager ID="ScriptManager1" Runat="server"> <Services> <asp:ServiceReference Path="ZipCodeService.asmx" /> </Services></asp:ScriptManager>
<script src="ZipCodeService.asmx/js" type="text/javascript"></script>
<script src="ZipCodeService.asmx/js" type="text/javascript"></script>
Consuming a Web ServiceConsuming a Web Service
ZipCodeService.GetCityAndState("98052", onCompleted); . . .function onCompleted (result){ window.alert(result);}
Handling ErrorsHandling Errors
ZipCodeService.GetCityAndState("98052", onCompleted, onFailed); . . .function onCompleted (result, context, methodName){ window.alert(result);}
function onFailed (err, context, methodName){ window.alert(err.get_message());}
Web Services
ASMX Wire FormatASMX Wire Format
POST /AtlasRC/ZipCodeService.asmx/GetCityAndState HTTP/1.1Accept: */*Accept-Language: en-usReferer: http://localhost:1997/AtlasRC/ZipCodePage.aspxUA-CPU: x86Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; ...)Host: localhost:1997Content-Length: 15Connection: Keep-AliveCache-Control: no-cache
{"zip":"98052"}
POST /AtlasRC/ZipCodeService.asmx/GetCityAndState HTTP/1.1Accept: */*Accept-Language: en-usReferer: http://localhost:1997/AtlasRC/ZipCodePage.aspxUA-CPU: x86Accept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; ...)Host: localhost:1997Content-Length: 15Connection: Keep-AliveCache-Control: no-cache
{"zip":"98052"}
Request
HTTP/1.1 200 OKServer: ASP.NET Development Server/8.0.0.0Date: Fri, 29 Dec 2006 21:06:17 GMTX-AspNet-Version: 2.0.50727Cache-Control: private, max-age=0Content-Type: application/json; charset=utf-8Content-Length: 16Connection: Close
["REDMOND","WA"]
HTTP/1.1 200 OKServer: ASP.NET Development Server/8.0.0.0Date: Fri, 29 Dec 2006 21:06:17 GMTX-AspNet-Version: 2.0.50727Cache-Control: private, max-age=0Content-Type: application/json; charset=utf-8Content-Length: 16Connection: Close
["REDMOND","WA"]
Response
JSON-encodedinput
JSON-encodedoutput
ScriptHandlerFactoryScriptHandlerFactory
• Wraps (replaces) default ASP.NET ASMX handler
• Extends ASMX model to support "special" URLs– JavaScript proxy generation (*.asmx/js)– Calls to Web methods (*.asmx/methodname)
• Gateway to ASP.NET AJAX ASMX extensions
<httpHandlers> <remove verb="*" path="*.asmx" /> <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, ..." /></httpHandlers>
ASMX Request HandlingASMX Request Handling
ScriptHandler-Factory
ScriptHandler-Factory
RestClient-ProxyHandler
RestClient-ProxyHandler
RestHandlerRestHandler
WebService-HandlerFactory
WebService-HandlerFactory
*.asmx
"Normal" ASMX calls
ASMX Extensions
*.asmx/js
*.asmx/methodname
HelperClasses
HelperClasses
Default ASMX handler
JSONJSON
• JavaScript Object Notation– Lightweight data interchange format– Easier to read and write (and less verbose) than
XML– Based on subset of JavaScript programming
language
• Default interchange format in ASP.NET AJAX– Supported on server by Microsoft.Web.Script.-
Serialization.JavaScriptSerializer class– Supported on client by Sys.Serialization.-
JavaScriptSerializer class
• JSON home page: www.json.org
JSON vs. XMLJSON vs. XML
Point p = new Point(100, 200);
{"IsEmpty":false,"X":100,"Y":200}{"IsEmpty":false,"X":100,"Y":200}
JSON
<?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>
<?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>
XML
The ScriptMethod AttributeThe ScriptMethod Attribute
• Optional attribute for script-callable Web methods
• Offers added control over wire format of callsProperty 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 ScriptMethodUsing 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 asXML rather than JSON
Page MethodsPage Methods
• Script-callable Web methods built into pages– Implemented in ASPXes, not ASMXes– Same efficiencies as ASMX Web methods
• Simpler than writing a full-blown Web service– 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 MethodsEnabling 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 = { ...}
var PageMethods = function() { PageMethods.initializeBase(this); this._timeout = 0; this._userContext = null; this._succeeded = null; this._failed = null;}PageMethods.prototype = { ...}
Defining a Page MethodDefining a Page Method
public partial class MyPage : System.Web.UI.Page{ [System.Web.Services.WebMethod] public static string[] GetCityAndState (string zip) { ... } ...}
PageMethods.GetCityAndState("98052", onComplete); . . .function onComplete(result){ window.alert(result);}
Calling a Page MethodCalling a Page Method
Page Methods
Built-In Web ServicesBuilt-In Web Services
• AuthenticationService– Front end to ASP.NET 2.0 membership service– Call through Sys.Services.AuthenticationService
proxy• Global instance of Sys.Services._AuthenticationService
• ProfileService– Front-end to ASP.NET 2.0 profile service– Call through Sys.Services.Profile proxy
• Global instance of Sys.Services._ProfileService
• Accessed through ScriptHandlerFactory on server– *_AppService.axd -> ScriptHandlerFactory
Using Using AuthenticationServiceAuthenticationServiceSys.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 PropertiesLoading 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());}
Pass null to load all profile properties
Saving Profile PropertiesSaving 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());}
Pass null to save all profile properties
Discussion