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
RewritableWebPartManager and the
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.
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
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
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.
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">
<rwwpl:PersonalizationLevel LevelID="uniqueid" Description="Description" />
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.
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
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
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
UpdatePanels. 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
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
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.
Private Sub Page_PreInit(sender As Object, e As System.EventArgs)
New PersonalizationLevel("AllPages", "All Pages"))
- 220.127.116.11 - 6/10/2008 - Initial release.