WebParts met een custom PersonalizationProvider
WebParts is één van de nieuwe onderdelen van Visual Studio 2005. Het leek mij leuk om eens te experimenteren met WebParts. Echter de hosting provider waar ik een WebPart enabled website neer zou kunnen zetten ondersteund geen SQL Server. …en zo begonnen de problemen want default heeft het WebParts onderdeel SQL Server nodig voor het persisteren van persoonlijke gegevens en dat gaat geheel automatisch. WebParts voorziet namelijk in de mogelijkheid om onderdelen van een webpagina op een voor een gebruiker zelf te kiezen plek neer te zetten en in of uit te schakelen. Kijk voor een eerste indruk eens op start.com. Start.com is een initiatief van Microsoft gebaseerd op WebParts en AJAX (Atlas).
Ik wil beginnen met het opzetten van een WebPart enabled ASP.NET website. Op mijn systeem heb ik geen SQL Server geinstalleerd zodat ik zeker weet dat er door ASP.NET niet toch (stiekem) gebruik van wordt gemaakt voor het persisteren van gegevens. Heb je zelf wel SQL Server Express Edition of 2005 draaien dan kun je tijdelijk de service uitschakelen via Control Panel > Administrative Tools > Services.
De WebPartManager beheerd alle WebPart controls op een pagina. Er is ook maar 1 WebPartManager noodzakelijk op een pagina.
Voeg een stylesheet toe met de naam main.css. Je gaat als volgt te werk.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
.col1 { background-color: blue; width: 200px; height: 200px; float: left; } .col2 { background-color: gray; width: 200px; height: 200px; float: left; } .col3 { background-color: white; width: 200px; height: 200px; float: left; } |
1 2 3 4 |
<div class="col1"></div><br />     <div class="col2"></div><br />     <div class="col3"></div><br /> |
protected void Page_Init(object sender, EventArgs e)
{
DisplayModeDropdown.Items.Clear();
foreach (WebPartDisplayMode mode in WebPartManager1.SupportedDisplayModes)
{
string modeName = mode.Name;
if (mode.IsEnabled(WebPartManager1))
{
ListItem item = new ListItem(modeName, modeName);
DisplayModeDropdown.Items.Add(item);
}
}
}
protected void DisplayModeDropdown_SelectedIndexChanged(object sender, EventArgs e)
{
String selectedMode = DisplayModeDropdown.SelectedValue;
WebPartDisplayMode mode = WebPartManager1.SupportedDisplayModes[selectedMode];
if (mode != null)
WebPartManager1.DisplayMode = mode;
}
Het zal nu enige tijd duren voor de applicatie echt start, met de volgende foutmelding (als de SQL Server service is uitgeschakeld of niet geinstalleerd).
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)
Je ziet nu dat .NET via de SQLPersonalizationProvider gepersonaliseerde gegevens probeert op te halen over de WebParts die op de pagina staan. Aangezien SQL Server niet aanwezig is kan er niet automatisch een database voor deze gegevens worden aangemaakt.
De custom PersonalizationProvider
Om de boel toch aan de praat te krijgen zijn er 2 mogelijkheden. Het installeren of starten van SQL Server of het maken van een eigen PersonalizationProvider. Dit laatste wil ik hier laten zien. Omdat ik niet wist hoe te beginnen heb ik zelf het web maar eens afgezocht op een custom PersonalizationProvider. Vooralsnog bestaan deze niet dus ik was aangewezen op mijzelf. Voorbeelden zijn er overigens ook niet te vinden over hoe een PersonalizationProvider te bouwen. Uiteindelijk na wat vogelen de oplossing, het resultaat een FileSystemPersonalizationProvider. Deze provider persisteert gepersonaliseerde WebPart gegevens op het filesysteem.
Als eerste moet er aan de solution een nieuw project worden toegevoegd.
using System.Web.UI.WebControls.WebParts;
using System.Configuration;
using System.IO;
Je kunt hier overigens de volledige code downloaden.
Bovenin de FileSystemPersonalizationProvider heb ik een static string opgenomen naar een pad waar de gepersonaliseerde gegevens mogen worden weggeschreven en worden opgehaald:
private static string PersonalizationPath = @"C:Documents and SettingssnoeiMy DocumentsVisual Studio 2005WebSitesWebPartsApp_Datapersonalization";
De belangrijkste verplicht te implementeren methodes die ik heb uitgewerkt om de boel draaiend te krijgen zijn:
Op basis van het WebPartManager ID, gebruikersnaam en het path van de webpagina met webparts zijn de sleutel om vast te stellen welke gegevens voor wie moeten worden opgehaald. Uiteindelijk bleek het dus vrij simpel om een custom PersonalizationProvider te schrijven. Overigens zou een aantal functies ook nog moeten worden geimplementeerd. Deze Provider is dus verre van stabiel te noemen het gaat echter om het idee. Voor de WebPart applicatie die we nu hebben is deze provider voldoende.
We hebben echter nog een probleem. De WebPartManager op onze default.aspx pagina moet gebruik gaan maken van de nieuwe Provider. Je gaat alsvolgt te werk:
<webParts>
<personalization>
<providers>
<!--clear/-->
<add name="FSPP" type="snoei.net.webparts.FileSystemPersonalizationProvider, snoei.net.webparts"/>
</providers>
</personalization>
</webParts>
Hiermee geven we aan dat we een specifieke PersonalizationProvider gebruiken, waar die kan worden gevonden en welke naam hij heeft.
De dropdown geeft nu de keuze tussen “browse” en “design”. In design mode kunnen WebParts worden verplaatst van ene naar de andere zone. Alle wijzigingen aan de layout worden vervolgens op het filesysteem opgeslagen. Voila, het klusje is geklaard. Nogmaals, de FileSystemPersonalizationProvider bevat een voorzet en is verre van compleet. Beter zou natuurlijk zijn om een MySQLPersonalizationProvider te bouwen of iets dergelijks. Eerlijk gezegd verwacht ik dat daar binnenkort wel iemand mee op de proppen komt.
Ik hoop dat ik hiermee heb laten zien hoe makkelijk het is om ASP.NET te customizen.
De source code: WebPartsTest.zip.