The Benefits of a Page Class...
Partial classes are a great new feature for the .Net 2.0 framework, because they can separate code into several classes, which is especially useful when working with large files. I always had the assumption, though, that I had to inherit directly from the Page class for this to work, but I found out I was wrong. Custom page classes can still be used to provide a variety of features to your site. I’ll illustrate this in this article. Microsoft came out with a new version of the Enterprise Library in January 2006 that has security and caching options built in. I like these features, and I tend to use them in my applications instead of the web-based caching. For instance, here is the override of the cache property.
public class PageBase : Page
{
private CacheManager _cache = null;
new public CacheManager Cache
get
if (_cache == null)
_cache = CacheFactory.GetCacheManager ( );
return _cache;
}
Whenever you use this.Cache or Me.Cache, you will get the instance of the cache manager from the enterprise library, instead of the web-based caching property. Notice that I keep an instance open locally. This is so that I don’t have to recreate the cache every time I reference it. For instance, look at this code:
if (this.Cache.Contains("mykey"))
return this.Cache.GetData("mykey");
By storing it locally, when getting the data, the object exists in this page lifecycle, which I feel is a little more efficient and not as resource intensive, because the object is destroyed at the end of page processing. I do this with several objects.
Want to include common client-script processing in your page? I created a CustomScriptManager class that has methods linked to custom client scripts, so that you can easily implement client UI in your page. In my example, I create a few helpers to alert the users of something, popping up an alert box. You could add features to do any myriad of things, such as interact with controls, perform DHTML behaviors, etc. To do so, the custom script manager class requires an instance of the Page.ClientScript (of type ClientScriptManager) class at startup. The property for exposing this appears below:
public CustomScriptManager CustomScripts
if (_customScripts == null)
_customScripts = new CustomScriptManager ( this.ClientScript );
return _customScripts;
This custom script manager class exposes the following methods. Note the call to PurifyPopupMessage; this method tidies up the output so we don't get any JavaScript errors.
public void PopupErrorNotification ( Exception ex )
string message = PurifyPopupMessage ( ex.ToString ( ) );
if (!_manager.IsClientScriptBlockRegistered ( "error" ))
_manager.RegisterClientScriptBlock ( this.GetType ( ), "error", "alert('" + message + "');", true );
public void PopupNotification ( string message )
message = this.PurifyPopupMessage ( message );
if (!_manager.IsClientScriptBlockRegistered ( "notify" ))
_manager.RegisterClientScriptBlock ( this.GetType ( ), "notify", "alert('" + message + "');", true );
You can build in whatever client-side features you have for your custom application. Next, I've built a security class, which is exposed in the page. Whenever the page runs, it determines who the user is by trying to get their windows credentials, although a forms-based approach could be easily implemented. This class can also be used for web and windows solutions, as if the context exists, then the user name is retrieved from it; otherwise, the windows user name is retrieved. This method also makes use of the security application block available in the enterprise library, which I wrote about previously. I exposed the IsAuthorized method in this class, so that it is available for the page.
public bool IsAuthorized ( string rule )
//Create a principal to represent the user
GenericPrincipal principal = new GenericPrincipal ( this.User, this.GetRoles ( ) );
IAuthorizationProvider authorization = AuthorizationFactory.GetAuthorizationProvider ( );
return authorization.Authorize ( principal, rule );
Now, say security for certain pages requires that users meet the requirements of a specific rule. The base class defines an authorization rule property that can be overridden. By default, it is empty:
public virtual string AuthorizationRule
get { return string.Empty; }
However, in the example attached, the administrative page overrides it and specifies the name of the rule:
public override string AuthorizationRule
get { return "AdministerSite"; }
The custom page class, in its constructor, performs the authorization whenever there is not a null or empty value. So, in the case of the administrative site, the constructor will perform the security validation with IsAuthorized to ensure the user has the proper credentials. Note that normally, this security authorization doesn't occur because most pages won’t need it; however, for the administrative site, there is by default the need for authorization, and so it can be authorized very easily.
public PageBase()
if (!string.IsNullOrEmpty(this.AuthorizationRule))
//Authorize the user against the targeted rule; if they don't meet
//the criteria, then throw an error
if (!this.Security.IsAuthorized(this.AuthorizationRule))
throw new System.Security.SecurityException();
Note that you can still do your own custom authorization by using the SecurityZone class.
In addition, your application has common application types that it shares throughout the application. A custom page class can expose these common classes, structures, or other types throughout the application. Furthermore, if storing a class, you can use a combination of caching to retrieve the object whenever requested. There are many features you can add to this custom page class to make them available throughout your entire application, reducing the amount of code needed for common tasks.