We're releasing a new Atlas build today (the bits are ready; hopefully the last minute stuff to get them online goes through smoothly). This build factors in a lot of the early feedback, focus on scenarios, some real integration with ASP.NET server controls, as well as more of the exploration into the world of script which was the focus of our PDC release.
Earlier I blogged about the overall Atlas architecture, XML script (a new declarative XML-based script ala XAML), and a rich Web application programming model. Check them out if you haven't had a chance to read them, as the concepts continue to move forward, and provide a foundation that remains intact. What is new is the renewed focus on enabling incremental enrichment of ASP.NET server-control based applications. Yes, we listened to a lot of the early feedback. In this post, I'll give a high level overview and quick tour of what to look for (ok it turned out to be longer than I expected, but hopefully a fun read regardless). I am looking forward to seeing a new round of comments, and follow-up questions/discussion as people get a chance to play with the bits.
You may wonder what about all those atlas server controls we had in our PDC release. Wasn't that our integration with ASP.NET pages? Well, in short, they're gone. These controls were really of out of place. They essentially enabled you to generate XML script using server controls. So in order to use them, you first had to learn XML script, and then you had to map those constructs into server control tags. And despite being server controls, you weren't able to use familiar server-side code and programming models to work against them. For this release, we put in a new set of server controls that have been developed with a different perspective.
Simply said, the premise is to preserve the server control model in terms development model and patterns, as well as existing ASP.NET 2.0 controls, while enabling key "AJAX" scenarios. The general approach is to model key rich Web application scenarios with a set of targeted controls, while allowing developers to continue to program on the server using managed code. I hope you like the new direction.
Incremental Refreshes and Partial Updates
The first interesting scenario we looked at is the ability to update pages incrementally. The idea is to suppress postbacks, and whole refreshes, and replace them with targeted and partial updates. We've provided this in a manner that is transparent to the page and the server developer as well. It is enabled using the new ScriptManager control as such:
<atlas:ScriptManager runat="server" id="scriptManager"
EnablePartialRendering="true" />
One little attribute with lots of magic behind it. Rather than performing a real postback, we simulate a postback using the familiar XMLHTTP object (or in Atlas using the Web.Net.WebRequest class). On the server, the page is processed as if it were a real postback in response to things like submit buttons or controls (including 3rd party ones) that call __doPostBack. For example Page.IsPostBack returns true. Server-side postback events continue to fire, and your event handlers continue to do work as they did before. Now, when it comes time to render the page, the ScriptManager needs to determine what portions of the page have changed. This is where another control, the UpdatePanel comes into play. You can use UpdatePanels to define logical regions within a single page that need to be updated as a chunk. For example, on a search page, I might have a regular <asp:TextBox>, an <asp:Button>, and an <asp:GridView> to display the results. The UpdatePanel would go around the grid as such:
<atlas:UpdatePanel runat="server" id="searchUpdatePanel">
<ContentTemplate>
<asp:GridView runat="server" ... />
</ContentTemplate>
</atlas:UpdatePanel>
The ScriptManager overrides the rendering of the entire page, and instead sends down HTML corresponding to UpdatePanels, in addition to other things like updated title, hidden fields (including view state), generated styles, updated scripts etc.
Now if you have multiple panels on your page, you probably want to update some panels some of the times, and other panels at other times. This is where triggers come into play. For example, if I want to update the search results only when the search button is clicked, I can add an event trigger as follows:
<atlas:UpdatePanel runat="server" id="searchUpdatePanel" Mode="Conditional">
<Triggers>
<atlas:ControlEventTrigger ControlID="searchButton" EventName="Click" />
</Triggers>
</atlas:UpdatePanel>
As you can see, this lets you start enabling a smoother postback-less experience for your users without having to fundamentally change the way you write apps. We have more ideas here, in terms of enabling controls to participate in deeper ways in terms of how they get updated on the client. This next level of intelligence will be added in a future release.
Timed Refreshes
The next interesting scenario was to enable portions of the page to be updated periodically (imagine the Stock symbol view on investor). Again, the idea is to enable this scenario without requiring you to learn XML script, or JavaScript for that matter. We provide a TimerControl that can be used in conjunction with UpdatePanels very simply:
<atlas:TimerControl runat="server" id="myTimer" Interval="60000" />
<atlas:UpdatePanel runat="server" id="stockViewUpdatePanel" Mode="Conditional">
<Triggers>
<atlas:ControlEventTrigger ControlID="myTimer" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:FormView runat="server" ... />
</ContentTemplate>
</atlas:UpdatePanel>
Here the TimerControl is smart about working with the ScriptManager to generate XML script and use the script Timer component already present in Atlas, while presenting a very familiar server control model. For example, I might decide to programmatically do some work, and conditionally update the UpdatePanel. As you'd expect the code might look like (very much like handling the Click event of a regular button):
<atlas:TimerControl runat="server" id="myTimer" Interval="60000"
OnTick="myTimer_Tick" />
<script runat="server">
private void myTimer_Tick(object sender, EventArgs e) {
if (/* some condition to determine if an update is needed */) {
stockViewUpdatePanel.Update();
}
}
</script>
TimerControl also demonstrates something that you'll see more of in time: Atlas-enabled server controls that happen to use Atlas for its richness and disciplined scripting approach to implement (and encapsulate) their client-side logic, rather than using raw JavaScript. (Check out the XML script generated by doing view source) Imagine atlas-enabled DataBound controls, and DataSource controls complementing each other on the client. I'm pretty excited!
AutoComplete
Surely, an Atlas release without some support for autocomplete in an AJAX world would be incomplete. Here the idea is to enable AutoComplete on an actual vanilla <asp:TextBox>. Enter ExtenderControls. (I'll have to blog about the technique in detail in the future)
<asp:TextBox runat="server" id="zipCodeTextBox" />
<atlas:AutoCompleteExtender runat="server" id="ace1">
<atlas:AutoCompleteProperties TargetControlID="zipCodeTextBox"
Enabled="true"
ServicePath="ZipCodes.asmx" ServiceMethod="GetZipCodes" />
</atlas:AutoCompleteExtender>
Yes, while the syntax might be a bit ugly (a constraint is to make this work on ASP.NET 2.0 without inventing new markup syntax), the design-time experience is actually pretty nice (if I may say so myself). Basically, the AutoComplete properties show up on the regular existing TextBox control (ala Extender Providers in Windows Forms). So the design-time story is drop in one of these extenders, and then customize auto-complete properties for any set of textboxes by selecting the textboxes themselves.
Floating Windows (or Overlays)
Apparently these are pretty popular (they're great when used judiciously). Again we used the extender control approach to enable any regular Panel to become a floating and draggable overlay.
<asp:Panel runat="server" id="helpPanel">...</asp:Panel>
<atlas:DragOverlayExtender runat="server" id="doe1">
<atlas:DragOverlayProperties TargetControlID="helpPanel" Enabled="true" />
</atlas:DragOverlayExtender>
The DragOverlayExtender makes use of the FloatingBehavior present in the drag/drop Atlas library to enable the panel to float around. Another example of using Atlas richness to implement server-side constructs. However we didn't stop here. Very likely, you also want to remember the location of the Panel. For now, you can use a profile property, but again in a very server-control-friendly manner. For example, if I have defined a profile property, "HelpPanelLocation", all I need to do is tell DragOverlayExtender about it, and add a profile service object to the page.
<atlas:ProfileScriptService runat="server" id="profileService" />
<atlas:DragOverlayExtender runat="server" id="doe1">
<atlas:DragOverlayProperties TargetControlID="helpPanel" Enabled="true"
ProfileProperty="HelpPanelLocation" />
</atlas:DragOverlayExtender>
The ProfileScriptService control takes care of issuing Web requests to the retrieve profile data, and to save changes (as the panel is repositioned), as well as makes profile data available for purposes of binding.
That's a quick tour of what to check out in terms of the server control model. As you might expect, the extender control model is extensible itself, so you can also build new extenders. We've just started here; there is a ways to go. I'd love to hear about other AJAXish scenarios you think are essential, and you'd love to see server controls enable.
One other thing that is noteworthy is we've included the debug version of Atlas scripts which preserve their formatting (otherwise lost to minimize size of release builds). These were always meant to be included. They contain some useful debug asserts, and we'll add more of those to enable more robust error reporting for script. You can enable debug mode by setting the "debug" property of the <compilation> section to true in web.config.
I want to re-emphasize that while we're enabling a more incremental server-control and server-centric programming model with this build, we're also committed to enabling the next generation of Web applications (should I call them Web 2.0 apps?) that tap into the full richness of today's browser platform. An example of this type of app is Virtual Places, a mashup bringing together Virtual Earth APIs, script components, lots of XML script, and data from various services. I'll delve into programming model once again and outline the overall spectrum of scenarios and vision for development of both server-centric and client-centric rich ASP.NET Web applications in a vision document I am planning. So stay tuned... I hope to get it out early next year!
In the meantime, happy holidays, and happy New Year!