Keeping It Simple

Enhance a Web-based RSS Reader Using the Microsoft ASP.NET AJAX Framework

CoverStory

LANGUAGES: VB.NET

ASP.NET VERSIONS: 2.0

 

Keeping It Simple

Enhance a Web-based RSS Reader Using the Microsoft ASP.NET AJAX Framework

 

By Wei-Meng Lee

 

In Keep It Simple I demonstrated how you can easily build an RSS Reader Web application (see Figure 1) using the various features of ASP.NET 2.0. Shortly thereafter Microsoft began releasing CTP releases of its new AJAX Framework, known by its codename of Atlas .

 


Figure 1: The RSS Reader application built in the previous article.

 

Toward the completion of this article, Microsoft renamed ASP.NET Atlas as ASP.NET 2.0 AJAX. The client-side Atlas JavaScript library is called the Microsoft AJAX Library; the server-side Atlas functionality that integrates with ASP.NET is called ASP.NET 2.0 AJAX Extensions. Throughout this article you may see traces of the word Atlas, but the functionality is otherwise unchanged.

 

Using the ASP.NET 2.0 AJAX Framework you can build more responsive ASP.NET Web applications by reducing the amount of times your page needs to be refreshed, and enrich the behavior of these applications by including new client-side functionality. I thought the best way to really learn a new framework is to actually build a project with it. And what better way to do it than to enhance an existing application?

 

In this article I ll demonstrate how you can enhance the original RSS Reader application using the ASP.NET 2.0 AJAX Framework. I suggest you download the source for the original RSS Reader application; you should understand how it works before following the instructions in this article. The original application is available.

 

What You Need

To use Atlas you must first install one of the following versions of Visual Web Developer:

 

You also need to download the latest version of the ASP.NET 2.0 AJAX Framework, which you ll find at http://atlas.asp.net/default.aspx?tabid=47&subtabid=471. Note: The version I used for this article is the July CTP release (you can check the changes between the ASP.NET AJAX ( Atlas ) CTP and the Beta 2 and RTM Releases from http://ajax.asp.net/files/AspNet_AJAX_CTP_to_Beta_Whitepaper.doc). For additional AJAX functionality you must download the ASP.NET AJAX Control Toolkit (previously known as the Atlas Control Toolkit) from http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=AtlasControlToolkit. See http://atlas.asp.net/atlastoolkit/Walkthrough/Setup.aspx for instructions on how to install the ASP.NET AJAX Control Toolkit, as well as Daniel N. Egan s article Working with the ASP.NET AJAX Control Toolkit.

 

Atlas-enable Your Existing Application

The first step toward Atlas-enabling the RSS Reader application is to add the necessary AJAX libraries and modify the Web.config configuration. To do so, you must perform the following steps:

  • Open the RSS Reader Web project in Visual Studio 2005.
  • Right-click the project name in Solution Explorer and select Add ASP.NET Folder | Bin to add a Bin folder to your project.
  • Right-click the Bin folder and select Add Existing Item. Select the Microsoft.Web.Atlas.dll library from the C:\Program Files\Microsoft ASP.NET\Atlas\v2.0.50727\Atlas.
  • Insert the code shown in bold in Figure 2 into the element of your application s Web.config file. (The highlighted code can be copied directly from the Web.config file located in the C:\Program Files\Microsoft ASP.NET\Atlas\v2.0.50727\Atlas folder.)
  • Insert the code shown in bold in Figure 3 into the element in your application s Web.config file.
  • Finally, insert the code shown in bold in Figure 4 into the element in your application s Web.config file.

 

 

 

 

  

   type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup">

    

     type="Microsoft.Web.Configuration.ConvertersSection"

     requirePermission="false" />

    

     type="Microsoft.Web.Configuration.WebServicesSection"

     requirePermission="false" />

      

       requirePermission="false" />

    

     type="Microsoft.Web.Configuration.ProfileServiceSection"

     requirePermission="false" />

  

 

 

 

   

     

     

     

     />

   

   

   

   

  

 

Figure 2: Place this code into the element of your application s Web.config file.

 

 

   

   

      

      

       type="Microsoft.Web.Services.ScriptHandlerFactory"

       validate="false"/>

      

      

       type="Microsoft.Web.Services.MultiRequestHandler"

       validate="false"/>

      

       type="Microsoft.Web.Globalization.GlobalizationHandler"

       validate="false"/>

      

      

       type="Microsoft.Web.Services.ScriptHandlerFactory"

       validate="false"/>

   

   

      

       type="Microsoft.Web.Services.ScriptModule"/>

      

       type="Microsoft.Web.Services.BridgeModule"/>

      

   

Figure 3: Place this code into the element of your application s Web.config file.

 

 

   

     

      assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>

     

      assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>

   

 

Figure 4: Place this code into the element in your application s Web.config file.

 

That s it! The RSS Reader project is now ASP.NET 2.0 AJAX-enabled.

 

Update Portions of a Page

The major restriction of the current RSS Reader application is that the entire page will refresh whenever you select a feed from the ListBox control. For example, if you are currently viewing the postings from MSDN and then switch to Engadget.com, the entire page needs to be reloaded to update the DataList control. Hence, the first thing we need to fix is the DataList control. We would want its content to update without causing the entire page to refresh. For this we ll use the Atlas UpdatePanel control. First, in Default.aspx, switch to Source View and add the Atlas ScriptManager control:

 

 

  EnablePartialRendering="True">

 

 

The ScriptManager control is the brain that enables all the various Atlas functions and should be positioned at the top of the page. The EnablePartialRendering attribute allows part of the page to be refreshed.

 

Next, add an UpdatePanel control and position it just above the DataList control. Then drag the DataList control into the UpdatePanel control. Figure 5 shows the before-and-after screen shot of the page. Figure 6 shows how the UpdatePanel control looks in code.

 


Figure 5: Embedding the DataList control within an UpdatePanel control.

 

 

  

   ForeColor="Black" DataSourceID="XmlDataSource1"

   CellPadding="2" BorderWidth="1px" BorderColor="Tan"

   BackColor="LightGoldenrodYellow">

   

   

     <%#XPath("title")%>

   

   

   

     <%#XPath("description") %>

    <%#XPath("pubDate")%>

   Link

   

   

   

   

     ForeColor="GhostWhite" />

   

   

  

 

Figure 6: The UpdatePanel control.

 

Notice that the DataList control is wrapped inside a ContentTemplate element. However, simply wrapping the DataList control with the UpdatePanel control is not enough to make the DataList update independently of the page. You need to add a trigger to the UpdatePanel control. Atlas triggers are used to specify the events that cause an UpdatePanel control to automatically refresh. For our example, let s add a ControlValueTrigger trigger (see Figure 7).

 

 

  

    ...

    ...

  

 

 

  

    ControlID="lstSubscriptions"

    PropertyName="SelectedValue" />

 

Figure 7: This type of trigger causes an update when the specified value of a control changes.

 

In this case, the DataList control will be updated whenever the SelectedValue property of the lstSubscriptions ListBox control changes. That is, whenever the user clicks on the list of feeds in the ListBox control.

 

Press F5 to test the application. In the list of blogs, click on any one of them and observe that the DataList control is now able to update itself without refreshing the entire page.

 

Displaying a Progress Message

Although the DataList control can now update itself without causing the entire page to refresh, you ll notice that the updates are sometimes slow and there is no way to know if the DataList control is updating or not. Hence, it would be useful to show a message to the user indicating that the control is being updated. To do so, you can use the UpdateProgress control, shown in bold in Figure 8.

 

 

   

      

         

          Text="Label" Width="500">

          Updating Blog Listings... Please wait.

         

      

   

   ...

   ...

Figure 8: The UpdateProgress control.

 

Here I ve used a Label control to display the message Updating Blog Listings... Please wait. You can also use an Image control to display an animated GIF image.

 

Press F5 to test the application. Now when you click on a feed you ll see the message and the message will disappear once the updating is complete (see Figure 9).

 


Figure 9: Displaying the message when the DataList control is being updated.

 

Sometimes the update is too fast and you won t have the time to catch the message. To prevent this, insert a Sleep method in the SelectedIndexChanged event of the lstSubscriptions control, as shown in Figure 10.

 

Protected Sub lstSubscriptions_SelectedIndexChanged( _

 ByVal sender As Object, _

 ByVal e As System.EventArgs) _

 Handles lstSubscriptions.SelectedIndexChanged

  Try

      System.Threading.Thread.Sleep(2000)

      '---Bind the XmlDataSource control to the

      ' selected item URL---

      XmlDataSource1.DataFile = _

         lstSubscriptions.SelectedItem.Value

  Catch ex As Exception

      DisplayError("Error displaying the feed.")

  End Try

End Sub

Figure 10: Insert a Sleep method in the SelectedIndexChanged event of the lstSubscriptions control.

 

Calling a Web Service from the Client

The next area we need to fix is the Verify Feed button (see Figure 11).

 


Figure 11: The Verify Feed button retrieves the feed title of a blog.

 

Before you subscribe to a feed, you must enter the feed URL and then click the Verify Feed button to retrieve the title of the feed. As usual, this will result in refreshing the entire page. A better way would be to rewrite the logic for verifying the feed (and obtaining the feed title) as a Web service so the client can directly connect to the Web service and obtain (and update) the feed title on the page, all without causing a page refresh.

 

Adding the Web Service

The first step is to add a new Web service to the project. In Solution Explorer, right-click on the project name and select Add New Item. Select Web Service and use its default name of WebService.vb. The new WebService.vb file should now be located in the App_Code folder of your project (see Figure 12).

 


Figure 12: Adding a new Web service to the project.

 

Double-click the WebService.vb file and import the following namespaces:

 

Imports System.Net

Imports System.IO

Imports System.Xml

 

Next, declare the two helper functions shown in Figure 13.

 

Private Function SendRequest( _

 ByVal URI As String, _

 ByVal requestType As String) As HttpWebRequest

  Dim req As HttpWebRequest = Nothing

  Try

      '---Creates a HTTP request---

      req = HttpWebRequest.Create(URI)

      req.Method = requestType '---GET or POST---

  Catch ex As Exception

      Throw New Exception("Error")

  End Try

  Return req

End Function

Private Function GetResponse( _

 ByVal req As HttpWebRequest) As String

  Dim body As String = String.Empty

  Try

      '---Get a response from server---

      Dim resp As HttpWebResponse = req.GetResponse()

      Dim stream As Stream = resp.GetResponseStream()

      '---Use a StreamReader to read the response---

      Dim reader As StreamReader = _

         New StreamReader(stream, Encoding.UTF8)

      body = reader.ReadToEnd()

      stream.Close()

  Catch ex As Exception

      Throw New Exception("Error")

  End Try

  Return body

End Function

Figure 13: The SendRequest and GetResponse functions.

 

The LoadFeed function will use the feed URL and retrieve the title of the feed, as shown in Figure 14.

 

Public Function LoadFeed( _

 ByVal URI As String) As String

  Dim req As HttpWebRequest

  Dim xmlDoc As XmlDocument = Nothing

  Try

    req = SendRequest(URI, "GET")

    Dim xmlData As String = GetResponse(req)

    xmlDoc = New XmlDocument()

     xmlDoc.LoadXml(xmlData)

    '---Select the title of the document---

    Dim titleNode As XmlNode = _

     xmlDoc.DocumentElement.SelectSingleNode( _

     "channel/title")

    Return titleNode.InnerText

  Catch ex As Exception

    Return String.Empty

  End Try

End Function

Figure 14: Retrieve the title of the feed.

 

Finally, add the VerifyFeed Web method so that it can be invoked directly by the client portion of the RSS application:

 

_

Public Function VerifyFeed(ByVal feedURL As String) As String

 '---Load the RSS feed XML document and extract the title---

 Return LoadFeed(feedURL)

End Function

 

Adding the Client-side JavaScript

To be able to invoke the Web method from the client side, you must write some client-side JavaScript. Add to the Source View of Default.aspx the JavaScript shown in bold in Figure 15.

 

...

  Untitled Page

...

Figure 15: Invoke the Web method.

 

Replace the original Verify Feed Button control (see Figure 16) with an HTML Input element:

 

 type="button"

 value="Verify Feed"

 onclick="return btnVerifyFeed_Click()" />

 


Figure 16: Replace the Button control with an HTML Input element.

 

This is because you don t want a postback to occur when the user clicks on the Verify Feed button; instead, it should invoke the JavaScript code. Finally, add the Services element within the ScriptManager element, as follows:

 

 EnablePartialRendering="True">

 

   

 

 

The Path attribute within the ServiceReference element specifies the Web service to invoke. Press F5 to test the application. Enter a feed URL and click the Verify Feed button. Notice that the page does not refresh and the feed title will be displayed on the page.

 

Subscribing to a Feed

After a feed is verified you can subscribe to it by clicking the Subscribe button. However, as usual, this will cause the ListBox control (showing the list of subscribed feeds) to be updated and hence cause the entire page to refresh. This is our next target for modification.

 

First, add an UpdatePanel control on top of the ListBox control (see Figure 17). Then drag the ListBox control onto the UpdatePanel control. Figure 17 shows the before-and-after effects.

 


Figure 17: Embedding the ListBox control within an UpdatePanel control.

 

Switch to the Source View of the page and add a trigger to the UpdatePanel control:

 

 

   

    AutoPostBack="True" Width="136px"

    Height="236px">

 

 

   

    ControlID="btnSubscribe"

    EventName="Click" />

 

 

This time you re adding a ControlEventTrigger trigger. This type of trigger causes an update to the UpdatePanel control when the specified control (btnSubscribe, in this case) raises a specified event (Click, in this case).

 

Press F5 to test the application. You can now verify a feed URL by clicking the Verify Feed button. To subscribe to the feed, simply click the Subscribe button and the newly subscribed feed will appear in the ListBox control. All this happens without causing a single page refresh!

 

Floating Panel

You can now subscribe to feeds without refreshing the page. In addition, switching from one feed to another does not cause any page refresh. Let s see what else we can improve.

 

If you use the application for some time you ll realize that you must constantly scroll to the top of the page before you can select another feed (see Figure 18). This is because the ListBox control is positioned at the top of the page. A better way would be to make the ListBox control a floating panel that will always appear at a particular position on the page.

 


Figure 18: You must scroll to the top of the page before you can select another feed.

 

First, add a Panel control below the Unsubscribe button (see Figure 19). Set the BorderStyle property of the Panel control to Solid. Then move the wordings Subscribed Feeds, the UpdatePanel control, and the Unsubscribe control into the Panel control. Figure 19 shows the before-and-after effects.

 


Figure 19: Moving the various controls into a Panel control.

 

Also, expand the width of the ListBox control so that it is wider (see Figure 20). Next, add to the page the AlwaysVisibleControlExtender control (found in the ASP.NET AJAX Control Toolkit). Configure the AlwaysVisibleControlExtender control as shown in Figure 21.

 


Figure 20: Widening the Panel control and adding the AlwaysVisibleControlExtender control.

 

 Height="50px" Width="300px">

 ...

 ...

 ID="AlwaysVisibleControlExtender1" runat="server">

 

   TargetControlID="Panel1"

   VerticalSide="Top"

   HorizontalSide="Right"

   HorizontalOffset="10"

   VerticalOffset="10"

   ScrollEffectDuration="0.1" />

Figure 21: Configure the AlwaysVisibleControlExtender control.

 

The AlwaysVisibleControlExtender control allows a Panel control to always remain visible. You configure it using the AlwaysVisibleControlProperties element. Its attributes are:

  • TargetControlID; the control that will always be visible.
  • VerticalSide; the vertical alignment of the control (Top or Bottom).
  • HorizontalSide; the horizontal alignment of the control (Left or Right).
  • HorizontalOffset; the number of pixels away from the horizontal edge of the window the control must be.
  • VerticalOffset; the number of pixels away from the vertical edge of the window the control must be.
  • ScrollEffectDuration; the length in seconds of the scrolling effect to last when the target control is repositioned.

 

Press F5 to test the application. You ll now see that the Panel control containing the ListBox and Button controls is always visible (see Figure 22).

 


Figure 22: The Panel containing the ListBox and Button controls is always visible.

 

Using Drag and Drop to Reposition Controls

The last modification we want to make to the RSS Reader application is to allow users to reposition the location of controls by drag-and-drop. A good candidate for this operation is the part of the page that allows users to verify and subscribe to a feed. Using a Panel control, enclose the two TextBox and Button controls (see Figure 23).

 


Figure 23: Enclosing the TextBox and Buttons controls within a Panel control.

 

Set the properties of the Panel control as follows:

  • Backcolor: #C0C0FF
  • BorderStyle: Double

 

The Source View of the Panel control looks like that shown in Figure 24.

 

 Height="50px" Width="532px" BackColor="#C0C0FF">

   Feed URL:

 

  Width="336px">

 

  onclick="return btnVerifyFeed_Click()" />

   Feed Title:

 

  Font-Bold="True" ForeColor="Red" Width="340px">

 

 

  Width="99px" OnClientClick="return

  document.getElementById('btnSubscribe').disabled = false;" />

  

Figure 24: Source View of the Panel control.

 

To make the Panel control drag-able, use the DragOverlayExtender control and configure it as follows:

 

 EnablePartialRendering="True">

 

   

 

 runat="server">

 

   TargetControlID="Panel2" />

 

Press F5 to test the application; you ll be able to drag and drop the Panel control anywhere on the page (see Figure 25).

 


Figure 25: Dragging the Panel control to any location on the page.

 

Remember the Last Drop Position

Although you can drag and drop the Panel control anywhere on the page, it won t be able to remember the last position when you restart the application. To do so, you must save the last drop position using the Profile service. In Web.config, add a new Profile property, as shown in bold here:

 

 

   

   

   

 

 

Uncomment the element in the Web.config file and set the setProperties and getProperties attributes as shown in bold here:

 

 setProperties="PanelLocation"

 getProperties="PanelLocation" />

 

This will cause the Profile property PanelLocation to be exposed to the client-side code. Back in the Source View of Default.aspx, add the element to the page and set its AutoSave attribute to true:

 

  

     TargetControlID="Panel2" />

  runat="server" AutoSave="true" />

 

Add the ProfileProperty attribute to the DragOverlayProperties control and set it to PanelLocation:

 

 

    TargetControlID="Panel2" ProfileProperty="PanelLocation"/>

 runat="server" AutoSave="true" />

 

That s it! Press F5 to test the application. You can now drag and drop the Panel control and then restart the application. The last drop position of the Panel control will be persisted and restored when you log in to the application.

 

Conclusion

You ve seen how easy it is to use the ASP.NET 2.0 AJAX Extensions to enhance the responsiveness of your current ASP.NET 2.0 applications. If you want to learn more about the Microsoft ASP.NET 2.0 AJAX Framework, check out my latest Short Cuts from O Reilly: Getting Started with Atlas (http://www.oreilly.com/catalog/atlaspdf/).

 

The source code accompanying this article is available for download.

 

Wei-Meng Lee (http://weimenglee.blogspot.com) is a Microsoft MVP and founder of Developer Learning Solutions (http://www.learn2develop.net), a technology company specializing in hands-on training on the latest Microsoft technologies. He is an established developer and trainer specializing in .NET and wireless technologies. Wei-Meng speaks regularly at international conferences and has authored and co-authored numerous books on .NET, XML, and wireless technologies. He writes extensively on topics ranging from .NET to Mac OS X. He is also the author of.NET Compact Framework Pocket Guide, ASP.NET 2.0: A Developer s Notebook (both from O Reilly Media, Inc), and Programming Sudoku (Apress).

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish