Putting It Together The PageTracker Example


Putting It Together ”The PageTracker Example

We'll now develop a control ( PageTracker ) that brings together the different ideas we've introduced in this chapter. The PageTracker control tracks the number of hits a page receives per application or per session and computes the round-trip time for a page. PageTracker exposes simple properties of several different types: PageTrackingMode (a custom enumeration type that we will define) and three built-in types: Int32 , String, and TimeSpan . PageTracker uses three different mechanisms for state management ( ViewState , Session , and Application ) and applies design-time attributes for designer support. We'll show the code for PageTracker first and then describe the details.

Listing 7-3 contains the code for the PageTrackingMode enumeration that is used by PageTracker.

Listing 7-3 PageTrackingMode.cs
 usingSystem; namespaceMSPress.ServerControls{ publicenumPageTrackingMode{ ByApplication, BySession, ByTripTime } } 

Listing 7-4 contains the code for the PageTracker control.

Listing 7-4 PageTracker.cs
 usingSystem; usingSystem.ComponentModel; usingSystem.Web.UI; usingSystem.Web.UI.WebControls; namespaceMSPress.ServerControls{ [ DefaultProperty("TrackingMode"), ] publicclassPageTracker:WebControl{ privateTimeSpan_tripTime; [ Category("Appearance"), DefaultValue("{0}"), Description("Theformattingstringusedtodisplaythe " +  "valuebeingtracked.") ] publicvirtualstringFormatString{ get{ strings=(string)ViewState["FormatString"]; return((s==null)? "{0}" :s); } set{ ViewState["FormatString"]=value; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicintHits{ get{ PageTrackingModemode=TrackingMode; objecto=null; if(mode==PageTrackingMode.ByApplication){ o=Page.Application[HitsKey]; } elseif(mode==PageTrackingMode.BySession){ o=Page.Session[HitsKey]; } 
 else{ thrownewNotSupportedException("Hitsisonly " +  "supportedwhenTrackingModeis " +  "PageTrackingMode.ByApplicationor " +  "PageTrackingMode.BySession"); } return((o==null)?0:(int)o); } } [ Category("Behavior"), DefaultValue(PageTrackingMode.ByApplication), Description("Thetypeoftrackingtoperform.") ] publicvirtualPageTrackingModeTrackingMode{ get{ objectmode=ViewState["TrackingMode"]; return((mode==null)? PageTrackingMode.ByApplication: (PageTrackingMode)mode); } set{ if(value<PageTrackingMode.ByApplication value>PageTrackingMode.ByTripTime){ thrownewArgumentOutOfRangeException("value"); } ViewState["TrackingMode"]=value; //Performcleanupoftheoldstorage. //WehavetocheckthatthePageisnotnull //becausethecontrolcouldbeinitialized //beforeitisaddedtothecontroltree. //NotethattheApplicationandSession //objectsarenotavailableinthedesigner. switch(TrackingMode){ casePageTrackingMode.ByApplication: if(Page!=null&&Page.Application!=null){ Page.Application.Remove(HitsKey); } break; casePageTrackingMode.BySession: if(Page!=null&&Page.Session!=null){ Page.Session.Remove(HitsKey); } break; casePageTrackingMode.ByTripTime: ViewState.Remove("TimeStamp"); break; } } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicTimeSpanTripTime{ get{ if(TrackingMode!=PageTrackingMode.ByTripTime){ thrownewNotSupportedException("TripTimeis " +  "onlysupportedwhenTrackingModeis " +  "PageTrackingMode.ByTripTime"); } return_tripTime; } } protectedoverrideHtmlTextWriterTagTagKey{ get{ returnHtmlTextWriterTag.Div; } } privatestringHitsKey{ get{ //CreateauniqueHitsKeyforthepageforkeying //inhitsperpageintheApplicationandSession //objects. returnPage.GetType().FullName; } } protectedoverridevoidOnLoad(EventArgse){ base.OnLoad(e); switch(TrackingMode){ casePageTrackingMode.ByApplication: //UpdatethepagehitsintheApplication //object.Thisoperationneedsalockbecause //multipleuserscouldaccessapageatthesame //time. lock(Page.GetType()){ Page.Application[HitsKey]=Hits+1; } break; casePageTrackingMode.BySession: Page.Session[HitsKey]=Hits+1; break; casePageTrackingMode.ByTripTime: //Getthetimestampforthepreviousrequest //fromViewStateandcomputethedifference //betweentheprevious //andcurrenttimestamp. objecttimeStamp=ViewState["TimeStamp"]; DateTimerequestTime=Context.Timestamp; if(timeStamp==null){ _tripTime=TimeSpan.Zero; this.Visible=false; } else{ this.Visible=true; _tripTime= (requestTime-(DateTime)timeStamp); } ViewState["TimeStamp"]=requestTime; break; } } protectedoverridevoidRenderContents(HtmlTextWriterwriter){ switch(TrackingMode){ casePageTrackingMode.ByApplication: casePageTrackingMode.BySession: writer.Write(FormatString,Hits); break; casePageTrackingMode.ByTripTime: writer.Write(FormatString,TripTime.TotalSeconds); break; } } } } 

The PageTracker control performs the following tasks :

  • Exposes properties of various types. The FormatString property is of type String , the Hits property is of type Int32 , the TrackingMode property is an enumeration type ( PageTrackingMode enumeration, defined in Listing 7-3), and the TripTime property is of type TimeSpan .

  • Exposes read/write properties ( FormatString and TrackingMode ) as well as read-only properties ( Hits and TripTime ).

  • Exposes virtual, or overridable, properties ( FormatString and TrackingMode ) as well as nonvirtual properties ( Hits and TripTime ).

  • Implements public properties ( FormatString , TrackingMode , Hits , and TripTime ) as well as a private property ( HitsKey ). The public properties have metadata that specifies how they appear within the property browser and whether they are serialized in the designer. The private property, however, does not require this metadata.

  • Maintains the state of its FormatString and TrackingMode properties across round-trips by using ViewState and indirectly uses ViewState to compute its TripTime property by round-tripping an old timestamp.

  • Maintains the state of its Hits property by using the Session object or the Application object (based on the tracking mode). PageTracker uses a lock when writing hits to the Application object because multiple threads could request the same page at the same time.

  • Updates the state of its Hits and TripTime properties in its OnLoad method. This method corresponds to the Load phase in a control's life cycle, which we'll discuss in Chapter 9, "Control Life Cycle, Events, and Postback." In brief, the Load phase occurs after page initialization during the initial request and subsequent to postback processing after a round-trip.

  • Applies the BrowsableAttribute and DesignerSerializationVisibilityAttribute attributes to its read-only properties ( Hits and TripTime ) so that these properties are not displayed in the property browser or serialized by the designer.

  • Overrides the TagKey property it inherits from WebControl in order to generate an HTML < div > tag instead of the default < span > that is generated by WebControl .

Figure 7-3 shows the properties of PageTracker in the property browser of Microsoft Visual Studio .NET, sorted by category. Among the properties displayed, we defined FormatString and TrackingMode , while PageTracker inherited the other properties from WebControl . The Hits and TripTime read-only properties are not displayed because we marked those properties as Browsable(false) . The HitsKey property does not appear either because it is private. The property browser never displays properties that are not public. Notice that the TrackingMode property displays a drop-down list that shows the values of the PageTrackingMode enumeration. We did not do any extra work to provide this functionality; the .NET Framework enables it by automatically associating an EnumConverter with an enumeration. The descriptive string at the bottom of the property browser displays the text in the DescriptionAttribute that we applied to the TrackingMode property.

Figure 7-3. The PageTracker properties displayed in Visual Studio .NET

graphics/f07hn03.jpg

Page That Uses the PageTracker Control

The ASP.NET page shown in Listing 7-5 has four instances of the PageTracker control. The first three instances correspond to the three tracking options specified in the PageTrackingMode enumeration. In the last instance of PageTracker , view state is disabled by setting EnableViewState="false" . As with enumerated properties in standard ASP.NET controls, the TrackingMode property is set declaratively by specifying the value of the PageTrackingMode enumeration without the qualifying PageTrackingMode type name .

Listing 7-5 PageTrackerTest.aspx
 <%@PageLanguage="C#" %> <%@RegisterTagPrefix="msp" Namespace="MSPress.ServerControls"  Assembly="MSPress.ServerControls" %> <html> <body> <formrunat="server"> <br> <asp:ButtonText="Submit" Runat="server" id="Button1" /> <br><br> <msp:PageTrackerid="Pagetracker1" TrackingMode="ByApplication" FormatString="PageHits:{0}" Width="200px"  Font-Name="Verdana" Font-Size="14pt" ForeColor="Black"  BackColor="#E0E0E0" runat="server" BorderStyle="None"  BorderColor="White" /> <br> <msp:PageTrackerid="Pagetracker2" TrackingMode="BySession" FormatString="SessionHits:{0}" Width="200px"  Font-Name="Verdana" Font-Size="14pt" ForeColor="Black"  BackColor="#E0E0E0" runat="server" /> <br> <msp:PageTrackerid="Pagetracker3" TrackingMode="ByTripTime"  FormatString="Round-TripTime:{0:F2}seconds"  Width="350px" Font-Name="Verdana" Font-Size="14pt"  ForeColor="Black" BackColor="#E0E0E0" runat="server" /> <br> <msp:PageTrackerid="Pagetracker4" EnableViewState="false"  TrackingMode="ByTripTime" Width="300px" Font-Name="Verdana"  Font-Size="14pt" ForeColor="Black" BackColor="#E0E0E0"  runat="server" /> <br> <br> </form> </body> </html> 

Open PageTrackerTest.aspx in your browser. Press the Submit button several times. Then close the browser window and open another browser window. Access PageTrackerTest.aspx again, and submit the page several times. The output in your browser should be similar to that shown in Figure 7-4. Note that the last instance of PageTracker is not displayed because when view state is disabled, the TripTime value cannot be computed. In that case, PageTracker sets its Visible property to false so that the control is not rendered.

Figure 7-4. PageTrackerTest.aspx accessed in a browser

graphics/f07hn04.jpg



Developing Microsoft ASP. NET Server Controls and Components
Developing Microsoft ASP.NET Server Controls and Components (Pro-Developer)
ISBN: 0735615829
EAN: 2147483647
Year: 2005
Pages: 183

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net