Introduction
When you use web parts in combination with a rewritten URL, the web parts will all be shared by all of the URLs that are rewritten to the same ASPX file. This library corrects this by replacing the WebPartManager
with RewritableWebPartManager
and the SqlPersonalizationProvider
with RewritableSqlPersonalizationProvider
.
It also provides additional functionality in the form of personalization levels. This allows you to share common personalization settings amongst multiple URLs. When a user is browsing, if no personalization is specified at a particular level, the personalization defined at a higher level is displayed instead. For example, in a web store scenario, you can allow the store operators to provide shared personalization that all users will see. Using levels, they can set personalization that will appear on all item pages, such as a disclaimer, and then override that personalization with a different disclaimer on a specific item's page.
Background
Web parts are a great new system for allowing personalization of web sites by end users that was introduced in ASP.NET 2.0. However, it isn't useful when used in combination with URL rewriting.
URL rewriting allows you to respond to requests from dynamic URLs by redirecting the handling to a different ASPX file on your server. This can be used to make your URLs more readable and to improve your search engine optimization (SEO), instead of using long query parameters. Some example systems for implementing this are UrlRewriter.net and UrlRewriting.net.
Using the code
RewritableSqlPersonalizationProvider
You should replace your SqlPersonalizationProvider
in the web.config with this provider. It acts to intelligently load and store the personalizations based upon a combination of the original request URL, the display mode, and the currently selected personalization level. Note that it can still be used by a standard WebPartManager
instead of a RewritableWebPartManager
, in which case, it will behave exactly like a normal SqlPersonalizationProvider
.
The basic premise is that if you are browsing, it finds the first personalization level that has any settings, and returns those settings when loading. If you are in any other display mode, it always returns the personalizations for the currently selected personalization level.
Obviously, this provider only works with the standard SQL database for data storage. However, you should be able to use the code to inherit from any other type of personalization provider as needed.
RewritableWebPartManager
Use this instead of a WebPartManager
in order to enable the features of RewritableSqlPersonalizationProvider
. It uses a RewritableWebPartPersonalization
class instead of the standard WebPartPersonalization
class to provide personalization settings. This class is accessible via the RewritablePersonalization
property to reduce the need for type-casting.
You can define personalization levels on it declaratively in the ASP.NET page, as shown below:
<rwwpl:RewritableWebPartManager ID="mgr" runat="server">
<RewritablePersonalization Enabled="true">
<PersonalizationLevels>
<rwwpl:PersonalizationLevel LevelID="uniqueid" Description="Description" />
</PersonalizationLevels>
</RewritablePersonalization>
</rwwpl:RewritableWebPartManager>
Each level mush have a unique LevelID
which is used to identify it for storage in the personalization database. It is this LevelID
that allows you to share the same personalization settings across multiple pages.
Personalization levels are used when browsing from the beginning of the list down. First, it checks for personalization on the URL that was requested. If none is found, it moves down to the first level in the list, then the second, etc.
If using this from user controls or content pages, you can find the current page's rewritable web part manager by calling RewritableWebPartManager.GetCurrent(page)
. This will return Nothing
if there is no web part manager or if the web part manager is not rewritable.
PersonalizationLevelDropDown
This is a helper control that you can add to your pages to allow a user to switch between personalization levels. Note that it will always reset its internal list of personalization levels during the PreRender
event, so if you want to customize it, you must do so after that point. Also, it automatically registers itself as a synchronous postback control with the AJAX ScriptManager
, if any.
Points of interest
Behavioral differences
A standard WebPartManager
will do a Server.Transfer
back to the originally requesting page whenever you change scopes between User and Shared in order to force a reload of the personalization data. The RewritableWebPartManager
does this, but must also do so at other times. Specifically, whenever you change personalization levels, or switch to or from the Browse display mode. Changing between the various editing display modes does not result in a Server.Transfer
.
You must be aware of this difference because you lose any postback data during this Server.Transfer
. Additionally, a Server.Transfer
will not work during an asynchronous AJAX postback. You must make certain that any postbacks that will result in a Server.Transfer
are performed synchronously if you are using AJAX UpdatePanel
s. You can do this by registering the control using the method ScriptManager.RegisterPostBackControl
, or declaratively using an <asp:PostBackTrigger>
tag in the Triggers
section of the UpdatePanel
.
Dynamically defining personalization levels
Sometimes, when using URL rewriting or content pages, you might want to dynamically add personalization levels to the page using code. To do so, they must be added before page initialization, during the page's PreInit
event. To do so, call the RewritableWebPartManager.RegisterPersonalizationLevel
shared method. If you pass insertAtBeginning
as True
, the level will be inserted at the beginning of the list. Otherwise, it will be added to the end of the list. Any level defined declaratively will fall between levels added with insertAtBeginning
and those added without it.
Example:
Private Sub Page_PreInit(sender As Object, e As System.EventArgs)
RewritableWebPartManager.RegisterPersonalizationLevel(_
New PersonalizationLevel("AllPages", "All Pages"))
End Sub
History
- 1.0.0.0 - 6/10/2008 - Initial release.