Tra ieri e oggi mi è capitato di sviluppare una web part per sharepoint portal, che fosse in grado di stampare a video la lista di tutte le sottoaree a partire dall'area corrente.
E' vero che una sottoarea in sharepoint viene gestita come un normalissimo site, ma è altrettanto vero che se vi viene in mente di ciclare la collezione SPSite.AllWebs, vi troverete di fronte a tutti i site, subsite e aree dell'intero sito.
Per far ritornare invece tutte le sottoaree a partire da quella corrente, vanno utilizzate le classi Area e AreaCollection del namespace Microsoft.Sharepoint.Portal.SiteData in questo modo:
//prendo il context del portal ... PortalContext context = PortalApplication.GetContext(this.Context);
//prendo il web site corrente SPWeb currentWeb = SPControl.GetContextWeb(this.Context);
if (currentWeb.Permissions.DoesUserHavePermissions(SPrights.ViewPages))
{
//prendo l'area corrente Area currentArea = AreaManager.GetArea(context, currentWeb.ID);
//ciclo tutte le sue sottoaree foreach(Area childArea in currentArea.Areas)
{
output.Write(childArea.Title + "<br />");
}
}
Se invece, volete avere non solo le sottoaree di quella corrente, ma anche tutte le aree di tutti i livelli a lei inferiori, non dovete far altro che creare una funzione ricorsiva, che cicli su se stessa.
Io per rendere la mia web part il più tipizzata possibile, mi sono creato due classi: PepSite.cs e PepSiteCollection.cs, rispettivamente per salvare le caratteristiche di una singola area e per avere una collezione di aree; una proprietà del mio oggetto custom è di tipo PepSiteCollection, e ciò mi permette di salvarmi in una collezione ad albero tutte le mie sottoaree. Ecco la funzione ricorsiva che fa tutto il lavoro:
public void GetAllAreas(PepSite currSite, Area currArea)
{
if(currArea.Web.Permission.DoesUserHavePermissions(SPrights.ViewPages))
{
foreach(Area childArea in currArea.Areas)
{
PepSite site = new PepSite();
site.Name = childArea.Title;
site.Url = childArea.WebUrl;
site.Guid = childArea.ID;
currSite.Sites.Add(site);
GetAllAreas(site, childArea);
}
}
}
protected override void RenderWebPart(System.Web.UI.HtmlTextWriter output)
{
PepSiteCollection coll = new PepSiteCollection();
PepSite startSite = new PepSite();
startSite.Name = "Home page";
startSite.Name = "http://localhost/";
startSite.Guid = Guid.NewGuid();
coll.Add(startSite);
PortalContext context = PortalApplication.GetContext(this.Context);
SPWeb startWeb = SPControl.GetContextWeb(this.Context);
Area startArea = AreaManager.GetArea(context, startWeb.ID);
this.GetAllAreas(coll[0], startArea);
}
Cosi' facendo avrete:
coll[0] --> Home page
coll[0].Sites[0] --> First subarea
coll[0].Sites[1] --> Second subarea
coll[0].Sites[0].Sites[0] --> Fisrt subsubarea
... e cosi' via ...